1. 高阶函数
2个特点满足一个就是高阶函数
1)我们给一个函数传入一个函数
2) 一个函数返回一个函数
1.1切片编程
// 装饰器模式 (对原本功能进行包装) 切片编程
function core(a, b, c, d) {
console.log('core...', a, b, c, d);
}
//
每个实例都有一个原型对象, core的原型对象是他的构造函数的原型prototype 即Function.prototype
// core的构造函数即Function 它所有实例都有一个__proto__属性 core.__proto__能找到before 即core.__proto__ === Function.prototype
Function.prototype.before = function (beforeFn) {
// this 指向 core
console.log(this);
/// (...args) 剩余运算符 把参数转为数组args
return (...args) => {
// 不能是普通函数 this会指向调用者环境 箭头函数中没有this 没有arguments 没有prototype 这些属性都会向上查找
beforeFn();
// ...解构运算符 把数组解构为一个个参数
this(...args); // 指向core()
};
};
let newFn = core.before(() => {
console.log('core before');
});
newFn(1, 2, 3, 4);
// 打印
// core before
// core... 1 2 3 4
2. 函数柯里化
柯里化也是一个高阶函数
2.1 先来个例子 判断一个值的类型
// 判断元素的类型
// 第一版 缺点 要用户输入判断的类型 容易出错 不灵活方便
function isType(str, type) {
console.log(Object.prototype.toString.call(str));
return Object.prototype.toString.call(str) == `[object ${type}]`;
}
console.log(isType('hello','String'));
console.log(isType(111,'Number'));
第一版 缺点 要用户输入判断的类型 容易出错 不灵活方便
优化后第二版:
// 优化后 第二版
// 让方法更具体一些 isNumber isString 不用写类型了 直接按类型函数调用
function isType2(type) {
return function(value) {
return Object.prototype.toString.call(value) === `[object ${type}]`;
};
}
let utils = {};
['String', 'Number', 'Boolean', 'Object'].forEach(method => {
utils[`is` + method] = isType2(method);
});
console.log(utils.isString(112));
console.log(utils.isNumber(112));
console.log(utils.isBoolean(111));
让方法更具体一些 isNumber isString 不用写类型了 直接按类型函数调用
isType2是一个高阶函数
2.2 什么是函数柯理化?
比如有个函数
function sum(a, b, c, d, e) {
return a + b + c + d + e;
}
可以通过 newSum(1, 2)(3)(5, 4) 或者newSum(1)(2)(3)(4)(5)调用
以下就是实现方法
// 柯理化函数
function sum(a, b, c, d, e) {
return a + b + c + d + e;
}
// arr就是我们要收集每次调用时传入的参数
const curring = (fn, arr = []) => {
let len = fn.length; // 函数的长度就是sum函数参数个数
return function(...args) {
let newArgs = [...arr, ...args];
if (newArgs.length == len) {
return fn(...newArgs);
} else {
return curring(fn, newArgs);
}
};
};
let newSum = curring(sum);
// 柯理化函数 每次入参都是一个参数
let a = newSum(1)(2)(3)(4)(5);
console.log(a);// 15
// 偏函数
let b = newSum(1, 2)(3)(5, 4);
console.log(b); // 15