在项目中经常遇到的东西,没有很深刻的理解。所以今天整理一下,网络上文章很多,出处就不详了吧。
JavaScript的一个特点:函数存在“定义时上下文”、“运行时上下文”和“上下文是可以改变的”。
call 和 apply
call和apply都改变了函数运行时候的上下文;他们存在的目的也是为了改变函数体内部this的指向。
例子:
function func(){}
func.prototype = {
member:1,
print:function(){ console.info(this.member)}
}
var temp = new func;
temp.print() // my member is :1
如果有一个对象tempmember = {member:2},我们想让它直接使用上面的print方法。就可以使用call或者apply方法:
tempmember = {member:2}
temp.print.call(tempmember) //my member is :2
temp.print.apply(tempmember)//my member is : 2
从上面的例子可以看出call和apply都可以动态改变this,当一个object没有某个方法,但是其他的有,就可以借助call或者apply用其他对象的方法来操作。
call和apply的区别
对于apply和call而言,两者作用是一样的(改变this),只是接受的参数不一样。
var func = function(arg1,arg2){}
func.call(this, arg1,arg2);
func.apply(this,[arg1,arg2])
其中this指向了当前的上下文,他可以是任何一个JavaScript对象(JavaScript中一切皆对象),call需要把参数按顺序传递进去,而apply则是把参数放数组里
例子:
1.数组之间的追加:
var array1 = [12,"foo",{name:"Joe",-2458}];
var array2 = ["Doe“,555,100]
Array.prototype.push.apply(array1,array2);//array1为this。array2为参数
/* array1 值为 [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */
2.获取数组中的最大值
var numbers = [5, 458 , 120 , -215 ];
var maxInNumbers = Math.max.apply(Math, numbers), //458
maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
bind方法:
方法与apply和call很相似,也是可以改变函数体内this的指向。
MDN的解释是:bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
var foo = {
bar:1;
eventBind:function(){
var self = this;$(".someClass").on("click",function(event){
console.info(self.bar) //1
})
}
}
可以写下面:
var foo = {
bar : 1,
eventBind: function(){
$('.someClass').on('click',function(event) {
console.log(this.bar); //1
}.bind(this));
}
}
在上面的代码中,bind创建了一个函数,当这个click事件绑定在被调用的时候,它的this关键词会被设置成被传入的值(这里指调用bind()时传入的参数),因此,这里我们传入想要的上下文this(这里其实是指foo),到bind()函数中,当回调函数被执行的时候,this便指向foo对象
最后:
apply、call、bind三者都是用来改变函数的this对象的指向的
apply、call、bind三者第一个参数都是this要指向的对象。也就是想指定的上下文
apply、call、bind三者都可以利用后续参数传参
bind是返回对应函数,便于稍后调用,apply、call则是立即调用
补充:
在ES6给出了替代数组的apply方法:使用扩展运算符