call,apply,bind一般用來指定this的環(huán)境两曼。
在了解他們的用法之前我們來看一段代碼
var a = {
user:"小焲",
fn:function(){
console.log(this.user);
}
}
a.fn(); //小焲
var b = a.fn;
b(); //undefined
看到這里是不是很奇怪皂甘,同樣的函數(shù),為什么結(jié)果不一樣悼凑。這是因為this的指向改變偿枕。如果想了解this指向問題請參考徹底理解js中this的指向,不必硬背户辫。
我們這里主要解決怎么讓b能夠輸出this.user渐夸。
1、call()
var a = {
user:"小焲",
fn:function(){
console.log(this.user); //小焲
}
}
var b = a.fn;
b.call(a);
通過call渔欢,我們把b函數(shù)的this指向改為了a墓塌,執(zhí)行之后就能輸出‘小焲’。
call方法除了第一個參數(shù)以外還可以添加多個參數(shù)奥额,如下:
var a = {
user:"小焲",
fn:function(e,ee){
console.log(this.user); //小焲
console.log(e+ee); //3
}
}
var b = a.fn;
b.call(a,1,2);
對于函數(shù)fn(a,b,c),如果我們要改變this指向苫幢,只需將之改為fn(null,a,b,c),第一個參數(shù)為你要指向的目標(biāo)垫挨,我這里取了null韩肝。這時this就默認指向window。
2棒拂、apply()
apply方法和call方法有些相似伞梯,它也可以改變this的指向,也可以傳參帚屉。它和call唯一的區(qū)別就是谜诫,apply的傳參必須用數(shù)組包裹,且只能穿數(shù)組這一個參數(shù)攻旦。如下
var a = {
user:"小焲",
fn:function(e,ee){
console.log(this.user); //小焲
console.log(e+ee); //11
}
}
var b = a.fn;
b.apply(a,[10,1]);
3喻旷、bind()
bind方法也可以改變this指向,但是和call牢屋、apply方法有些不同且预。
不過我們先來看看bind也像call一樣使用會如何。
var a = {
user:"小焲",
fn:function(){
console.log(this.user);
}
}
var b = a.fn;
b.bind(a);
//未執(zhí)行
是不是很奇怪烙无。這就是bind和call锋谐、apply方法的不同,實際上bind方法返回的是一個修改過后的函數(shù)截酷。
var a = {
user:"小焲",
fn:function(){
console.log(this.user); //小焲
}
}
var b = a.fn;
var c = b.bind(a);
c();
所以在對事件函數(shù)進行變更this指向的時候多用bind涮拗,如果使用call就視為函數(shù)自執(zhí)行了,那不是我們想要的。
同樣樣bind也可以有多個參數(shù)三热,并且參數(shù)可以執(zhí)行的時候再次添加鼓择,但是要注意的是,參數(shù)是按照形參的順序進行的就漾。
var a = {
user:"小焲",
fn:function(e,d,f){
console.log(this.user); //小焲
console.log(e,d,f); //10 1 2
}
}
var b = a.fn;
var c = b.bind(a,10);
c(1,2);