修改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;
}
}