HIHI,又來每週一篇惹,上禮拜的[筆記][JavaScript]認識JavaScript中的「this」大致上說明了JavaScript中的「this」,但是這個「this」是可以在呼叫function的時候用函式重新指定的,那些函式就是call()
、apply()
和bind()
,也是這次要說的主題。
首先說明call()
,他再呼叫function的時候可以使用多個參數,第一個為要為這個function指定的「this」,第二個開始會傳進去該function內當作引數,例如:
//首先宣告兩個物件
var objA = {
Name:'A',
};
var objB = {
Name:'B',
writeName:function(age){
console.log(this.Name + ' is ' + age + ' years old.');
},
};
//呼叫objB的function並給他參數
objB.writeName(17); //會得到'B is 17 years old.'
//這時候我們利用call()來呼叫objB內的function並指定他的this為objA
objB.writeName.call(objA,19); //會得到'A is 19 years old.'
當我們用call()
去呼叫objB.writeName()
時,第一個參數放進objA,代表我將「this」指定給objA,所以他的this.Name
會變成objA.Name
,而第二個參數開始,會依序傳進funciton內當作引數,所以17會被objB.writeName()
的age接收,最後印出「A is 19 years old.」
再來我們用apply()
來呼叫objB.writeName()
看看,apply()
比較不同的是他只有兩個參數,第一個依然是為執行的function去指定「this」,而第二個參數必須提供陣列,陣列裡面每個位置的值依然會被依序傳入function內當作引數,例如:
objB.writeName.apply(objA,[20]); //會得到'A is 20 years old.'
當我們用apply()
去呼叫objB.writeName()
時,第一個參數一樣是指定「this」為objA,而第二個陣列中的所有項目會依序被傳入function內當作引數,所以陣列中第一個值20,會被傳進objB.writeName()
的age裡面,最後印出最後印出「A is 20 years old.」。
最後來試看看bind()
,給他的參數內容就和使用call()
一樣,第一個參數指定「this」,第二個參數開始則會依序傳入被呼叫的function內當作引數,但是不一樣的是bind()
他會創建一個新的函式,例如:
//把用bind創建的函式給變數func,這時候bind設定的「this」(objA)和參數(20)會同時被指定到func中
var func = objB.writeName.bind(objA,22);
func(); //執行後會得到'A is 22 years old.'
//也可以只設定「this」不設定其他參數值,等到呼叫的時候再給
var func1 = objB.writeName.bind(objA);
//執行func1,並給參數值
func1(24); //執行後會得到'A is 24 years old.'
當我們使用bind()
的時候,他並不會執行呼叫的函式,而是會創建一個新的函式,而你可以在bind()
的時候同時設定「this」或其他參數值給新函數。
所以用以下三種方式去改變objB.writeName()
的「this」值所得到的結果都是相同的:
//call()
objB.writeName.call(objA,19);
//apply()
objB.writeName.apply(objA,[19]);
//bind()
var func = objB.writeName.bind(objA,19);
func();
//也可以這麼寫
var func1 = objB.writeName.bind(objA);
func1(19);
//都會回傳'A is 19 years old.'
以上就是這三個函式的使用方法,如果我有觀念錯誤或解釋不清楚的地方,還麻煩各位大大指點了,謝謝大家!
原來除了 call 和 apply 還有 bind,
這三個函式在剛接觸 JS 時真的非常難理解。
哈哈,我一開始就直接跳過
是之後才回來重看的