首先三者都可以用于改变当前的this指向
有个比较有意思的:
var name="lucy";
let obj={
name:"martin",
say:function () {
console.log(this.name);
}
};
obj.say(); //martin,this指向obj对象
setTimeout(obj.say,0); //lucy,this指向window对象
正常情况下调用对象下边的方法,this指向的是当前这个对象;但是在setTimeout里边this指向的是window。
因为 say 方法在定时器中是作为回调函数来执行的,因此回到主栈执行时是在全局执行上下文的环境中执行的,但我们需要的是 say 方法中 this 指向obj对象,因此我们需要修改 this 的指向。
apply
apply方法接受2个参数,第一个参数:往往传入this,不传入或者说null,undefined的时候,则默认传入window。第二个参数参数:数组的形式传入。会立即执行改变this指向1次
- 用法 改变this指向:下边演示改变settimeout 中回调函数的this指向
var name="martin";
var obj={
name:"lucy",
say:function(year,place){
console.log(this.name+" is "+year+" born from "+place);
}
};
var say=obj.say;
setTimeout(function(){
say.apply(obj,["1996","China"])
} ,0); //lucy is 1996 born from China,this改变指向了obj
say("1996","China") //martin is 1996 born from China,this指向window,说明apply只是临时改变一次this指向
- 改变传入参数
var arr=[1,10,5,8,3];
console.log(Math.max.apply(null, arr)); //10
Math.max函数的参数是以参数列表,如:Math.max(1,10,5,8,3)的形式传入的,因此我们没法直接把数组当做参数,但是apply方法可以将数组参数转换成列表参数传入,从而直接求数组的最大值。
call
和apply功能类似也可以改变this执行,且立即执行改变this指向一次。区别是,可以传多个参数:第一个参数也是this(不传的话会是window),后边可以跟多个参数。
var arr=[1,10,5,8,3];
console.log(Math.max.call(null,arr[0],arr[1],arr[2],arr[3],arr[4])); //10
bind
bind与call apply功能也类似。第一个参数也是this,后边可以传入多个参数(与call类似)。
区别
1: 第二个以及后边的参数 可以分多次传入;
2:返回一个函数 不会立即执行;
var arr=[1,10,5,8,12];
var max=Math.max.bind(null,arr[0],arr[1],arr[2],arr[3])
console.log(max(arr[4])); //12,分两次传参
最后运行会把所有参数放在一起运行;
总结一遍:apply,call,bind三者的区别
- 相同
三者都可以改变函数的this对象指向。
三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window。 - 不同
三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入。
bind 是返回绑定this之后的函数,便于稍后调用;apply 、call 则是立即执行
网友评论