手写call apply bind

84 阅读1分钟

前言

call apply bind三个方法都是函数调用过程中,手动绑定this值;

call第一个参数为绑定this值的上下文环境,其余参数为要执行函数的入参

apply第一个参数为绑定this值的上下文环境,第二参数为执行函数入参所构建的数组

bind返回一个绑定好this值的函数,第一个参数为绑定this值的上下文环境,其余参数为要执行函数的入参。

// 这里不能使用箭头函数,会出现this指向问题
Function.prototype.myCall = function(ctx, ...rest) {
    // 校验ctx入参
    ctx = ctx && typeof ctx === 'object' ? ctx : window;
    // 使用symbol变量,防止覆盖
    const fn = Symbol();
    ctx[fn] = this;
    // 使用调用对象方法的形式,来修改this指向
    const result = ctx[fn](...rest);
    // 删除绑定的属性,反正污染ctx
    delete ctx[fn];
    return result;
}

Function.prototype.myApply = function(ctx, arg) {
    //校验入参ctx
    ctx = ctx && typeof ctx === 'object' ? ctx : window;
    const fn = Symbol();
    ctx[fn] = this;
    const result = ctx[fn](...arg);
    delete ctx[fn];
    return result;
}

Function.prototype.myBind = function(ctx, ...rest) {
    // 校验入参ctx
    ctx = ctx && typeof ctx === 'Object' ? ctx : window;
    // 缓存this
    const _this = this;
    return function(...arg) {
        const fn = Symbol();
        ctx[fn] = _this;
        // 两次入参进行合并,实现函数的柯里化
        const result = ctx[fn](...[...arg,...rest]);
        delete ctx[fn];
        return result;
    }
}