手写bind,call,apply,curry,compose函数

212 阅读1分钟

       bind,call,apply 三者都是用于改变函数体内this的指向,但是bindapplycall的最大的区别是:bind不会立即调用,而是返回一个新函数,applycall都是为了改变某个函数运行时的上下文而存在的(就是为了改变函数内部this的指向);applycall的调用返回函数执行结果;apply的第二个参数是一个参数数组,call的第二个及其以后的参数都是单个的元素。

Function.prototype.myBind = function () {    
    let _this = this;    
    let context = [].shift.call(arguments);    
    let args = [].slice.call(arguments);    
    return function () {        
        return _this.apply(context, [].concat.call(args, [].slice.call(arguments)))    
    }
}
Function.prototype.myCall = function (target, ...args) {    
    let context = target || global;    
    context.fn = this;    
    const result = context.fn(...args);    
    delete context.fn;    
    return result;
}

Function.prototype.myApply = function (target, arr) {    
    let context = target || global;    
    context.fn = this;    
    if (!arr) {        
        return context.fn();    
    }    
    const args = arr;    
    const result = context.fn(...args);    
    delete context.fn;    
    eturn result;
}

所谓柯里化,就是把一个多参数的函数转化为单一参数函数

function curry(fx, ...args) {    
    const len = fx.length;    
    return args.length >= len ? fx.call(null, ...args) : curry.bind(fx, ...arguments)
}
function add(a,b,c){    
    return a+b+c;
}
console.log(curry(add)(1,2,3)===curry(add)(1)(2)(3)); // true
console.log(curry(add)(1)(2)(3)===curry(add)(1,2)(3)); // true
console.log(curry(add)(1,2)(3)===curry(add)(1)(2,3)); // true

函数合成是把多个单一参数函数合成一个多参数函数的运算

function compose(...args){    
    return args.reduce((f,g)=>(...args)=>f(g(...args)))
}