call,apply,bind主要用法在执行函数的时候能改变函数中的this指向,
call
call(this, arguments…),第一个参数传入想要指向的this
- 把THIS(FN)中的"函数里面的THIS关键字"修改为第一个参数值(OBJ),也就是像类里面的this.name。。如果使用call那这个this就是传进来的
- 把THIS(FN)执行,把第二个及以后接受的参数值传递给函数(10,20)
call的内部机制其实是执行调用它的函数也就是this()
fn.call(OBJ, 10, 20);
Function.prototype.call=function callAA(){
//=>1.把THIS(FN)中的"**函数里面的THIS关键字**"修改为第一个参数值(OBJ)
//=>2.把THIS(FN)执行,把第二个及以后接受的参数值传递给函数(10,20)
this(10,20)
//函数的this指向一般都是.前面调用的或者在不严格模式下的window,所以这个this可以理解为fn,内部直接执行调用的函数
};
window.name = '预约'
let fn = function (){
console.log(this.name);
};
let obj = {
name:'OBJ',
fn:fn
};
fn();//this => window,'预约'
obj.fn();//this => obj,"OBJ"
fn.call(obj);//this:obj, 'OBJ'
主要看到一个经典的题目
function fn1(){console.log(1);}
function fn2(){console.log(2);}
fn1.call(fn2);
//1,这个没有疑问,立即调用执行fn1,打印出1
fn1.call.call(fn2);
//2,不应该是1吗?第一个call里面调用的其实是fn1.call(),但是前面的call把fn1.call里面的this改为fn2,所以当fn1.call()执行的时候就会执行this() => fn2()所以打印出来2
Function.prototype.call(fn1);
//无输出,Function.prototype只是一个原生函数对象,调用的话什么也没输出
Function.prototype.call.call(fn1);
//1,和上面的2一样call把Function.prototype.call里面的this改变了,最后改变成this() => fn1()
console.log(fn1.call.call.call.call===Function.prototype.call)
//true,因为call本来就是一个函数,call.call和fn.call都是找原型上的call
fn1.call.call.call.call(fn2)
//2,第一个call传入this=fn2给第二个,所以无论多长的call链最后还是到第二个call中的this() => fn2()就停止
apply
和call的区别在于第二个参数传入为数组,fn.apply(obj,[10, 20]);
bind
和call区别在于bind是等待执行的,类似于闭包需要后续调用才会执行,可以用在异步调用事件等
window.name = '预约'
let fn = function (){
console.log(this.name);
};
let obj = {
name:'OBJ',
fn:fn
};
fn();//this => window,'预约'
obj.fn();//this => obj,"OBJ"
fn.bind(obj);//返回值为fn函数
fn.bind(obj)();//this:obj, 'OBJ'