手写call、apply、bind

98 阅读1分钟

修改this的方式

1、默认绑定:在非严格模式下,this 默认指向全局对象。在严格模式下,this 默认指向 undefined
2、隐式绑定:调用位置是否有上下文对象,或者是否被某个对象拥有或者包含,那么隐式绑定规则会把函数调用中的 this 绑定到这个上下文对象
3、显式绑定:通过 call、apply、bind 显式改变函数内 this 指向
4、new 绑定:new 调用函数会创建一个全新的对象,并把 this 指向这个新创建的对象

通过 call、apply、bind 等可以显示绑定 this,修改调用函数的 this 上下文。call、apply 的区别在于参数,call 只能一个一个传参,apply 第二个参数可以传入数组。bind是返回新的函数,该函数执行时会用我们传出的上下文对象修改this

call

Function.prototype.call = function(context, ...args){
    context = context || window;
    // 将调用call的方法赋值给context
    context.fn = this;
    // 通过隐式绑定,修改调用方法的上下文
    context.fn(...args);
    delete context.fn;
}

apply

Function.prototype.apply = function(context, args){
    context = context || window;
    context.fn = this;
    context.fn(...args);
    delete context.fn;
}

bind

bind会返回一个新的函数,如果这个返回的新的函数作为构造函数创建一个新的对象,那么此时 this 不再指向传入给bind的第一个参数,而是指向用new创建的实例

Function.prototype.bind = function(context, ...args){
    context = context || window;
    context.fn = this;
    // 返回新的方法
    return function(...params){
        args = args.concat(params);
        // 合并参数
        context.fn(...args);
        delete context.fn;
    }
}