作爲一名合格的前端開發者,大家都知道JavaScript中的this指向問題是一件很苦惱的事情,因爲你稍不留意他就跳來跳去 很多Bug就是在不經意間this上下文出錯導致。call()、apply()、bind()的作用也恰恰與this有關,因爲在項目開發中很少用到,大家只知道他們是爲了:“改變this指向”,但是這樣草草了事的答案,只會暴露出你對它們“根本不瞭解”!!OK,先來看一段簡單的代碼:
// window
var name, age, love;
function Create(name, age, love) {
this.name = name
this.age = age
this.love = love
}
Create('王二牛', '18歲', '唱歌') //調用函數 Create()
console.log(name, age, love) //輸出結果 王二牛 18歲 唱歌
再此之前先了解call()函數的定義:
call():它可以用來調用所有者對象作爲參數的方法。通過 call(),能夠使用屬於另一個對象的方法。
首先,在window中定義了name age love三個變量,當執行Create()函數時 函數內部的this毫無疑問指向window,因爲他沒有具體指向調度者是誰,所以只能是window對象,其實此處調用相當於下面的寫法:
Create.call(window, '王二牛', '18歲', '唱歌') //編譯器默認加上了call、並且指向window
然後,我們使用call()、()apply()函數改造一段改變this指向的代碼:注意第一個參數此刻不是window對象,而是Person對象,故this不再指向winodw。
// call
var name, age, love;
var Person = {} //創建新對象
function Create(name, age, love) {
this.name = name
this.age = age
this.love = love
}
Create.call(Person, '王二牛', '18歲', '唱歌') //第一個參數指向Person對象
console.log(Person) // 輸出結果 {name: "王二牛", age: "18歲", love: "唱歌"}
語法:call()、apply()函數的第一個參數都是this的指向,即調用者。第二個參數及其以後的所有參數都是Create函數的實參;
區別:call()第二個以及之後的若干參數可以是string、function、Array、object等,且可以有多個參數;
apply()只能有兩個參數,並且實參只能以數組類型傳遞到調用函數內部,這也是兩者唯一的區別;
接着我們來看看bind()函數的作用:
bind():將函數綁定到某一個特定的對象上,調用函數內的this指向的值會被綁定到傳入bind()第一個參數的值,例如,f.bind(obj),實際上可以理解爲obj.f();
// bind
var name = '張三瘋', age = 88;
var obj = {
name: '楊過',
age: 18,
sex: '男',
fun: function () {
console.log(this.name + " 今年" + this.age + "歲," + "性別:" + this.sex)
}
}
var Girl = {
name: "小龍女",
age: 16,
sex: "女"
}
obj.fun() // 輸出結果 楊過 今年18歲,性別:男
obj.fun.bind(window)() // 輸出結果 張三瘋 今年88歲,性別:undefined
obj.fun.bind(Girl)() // 輸出結果 小龍女 今年16歲,性別:女
上述代碼,直接調用 obj.fun() 函數、內部的this指向了 obj 自身對象,因爲調度者是obj自身。
當使用 bind 函數調用時 bind的第一個參數指向了 window 對象,即改變了 this 指向 window 中只定義了變量 name、age ,sex未定義,所以輸出結果爲“張三瘋 今年88歲,性別:undefined”。
第三次調用改變了this指向爲Girl對象,那麼她的小龍女就上場了。
注意: bind()除了返回是函數以外,它的參數和 call 一樣。
如果我的博客幫助你解決了開發問題,請不要吝嗇你的小紅心哦!❤