call()、apply()、bind() 的用法与区别
call、apply、bind的作用是改变函数运行时this的指向
1、方法调用模式:
当一个函数被保存为对象的一个方法时,如果调用表达式包含一个提取属性的动作,那么他就是被当做一个方法来调用,此时的this被绑定到这个对象。例如
var a = 1;
var obj = {
a: 2,
fn: function(){
console.log(this.a);
}
}
obj.fn();//2
此时的 this 是指 obj 这个对象,obj.fn()实际是 obj.fn.call(obj) ,事实上谁调用这个函数,this就是谁。
注意:补充一下,DOM对象绑定事件也属于方法调用模式,因此它绑定的this就是事件源DOM对象。
如下图所示:
document.addEventListener('click', function(e){
console.log(this);//document
setTimeout(function(){
console.log(this);//window
}, 200);
}, false);
解析:点击页面监听click事件属于方法调用,this指向事件源DOM对象,即 obj.fn.apply(obj),setTimeout内的函数属于回调函数,可以这么理解,f1.call(null, f2),所以this指向window。
2、例子说明用法跟区别:
var name = '小明',age = 18;
var obj = {
name : '小张',
heAge : 22,
heFun :function (adin,dre) {
console.log(this.name +"年龄"+this.age,adin+dre);
}
}
var test = {
name:'大强',
age:'66'
}
obj.heFun.call(test,'成年','一号');//大强年龄66 成年一号
obj.heFun.apply(test,['成年','二号']);//大强年龄66 成年二号
obj.heFun.bind(test,'成年','三号')();//大强年龄66 成年三号
从上面三个结果不难看出:
call 、bind 、 apply 这三个函数的第一个参数
都是this 的指向对象
,第二个参数差别就来了:
1.call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 obj.heFun.call(test,‘成年’, … ,‘string’ )。
2.apply 的所有参数都必须放在一个数组里面传进去 obj.heFun.apply(test,[‘成年’, …, ‘string’ ])。
3.bind 除了返回是函数
以外,它 的参数和 call 一样。
注意:当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!