call和apply
call和apply都是函数的正常调用方法,它们位于Function.prototype中,其中第一个参数是this,可以改变函数体内部 this的指向,当目标对象没有某个方法时,而其它对象有,则可以调用这个其它对象的方法并call或apply目标对象,目标对象就能使用这个方法,例如arguments是个伪数组,它没有数组的slice方法,所以可以用call或apply来改变this:
var arr = Array.prototype.slice.call(arguments)
第一个之后的参数就是函数的参数,当参数确定时则用call方法 fn.call(asThis, p1,p2)
,参数不确定时或者想把一堆数一个个传入时,用apply方法 fn.apply(asThis, params)
,此时就会将params中的数一个一个传入函数,例如:
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
Array.prototype.push.apply(array1, array2);
/* array1 值为 [1, 2, 3, 4, 5, 6] */
bind
bind 与 apply 和 call 相似,但它不会调用函数,而是创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。示例:
下面这是一个不好的做法:
var foo = {
bar : 1,
eventBind: function(){
var _this = this;
$('.someClass').on('click',function(event) {
console.log(_this.bar); //1
});
}
}
由于上下文环境从 eventBind:function(){ }
过渡到 $(‘.someClass’).on(‘click’,function(event) { })
时发生了改变,this不再指向foo,所以要在之前用_this把this的值保留,但是这么做很丑,用bind就优雅多了
var foo = {
bar : 1,
eventBind: function(){
$('.someClass').on('click',function(event) {
console.log(this.bar);
}.bind(this));
}
}
apply、call、bind比较:
var obj = {
x: 81,
};
var foo = {
getX: function() {
return this.x;
}
}
console.log(foo.getX.bind(obj)()); //81
console.log(foo.getX.call(obj)); //81
console.log(foo.getX.apply(obj)); //81
bind()方法后面多了一对(),也就是说当你希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用 bind() 方法。而 apply/call 则会立即执行函数。
总结:
apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
apply 、 call 、bind 三者都可以利用后续参数传参;
bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。
网友评论