介紹JavaScript中function原生的三個方法(method)與用法
後面會講function borrowing 與 function currying
在JavaScript中,function會有三個原生的方法,分別是call()、apply()、bind(),而這三個方法的目的都是一樣的,為了改變this的指向。
記得在最前面的章節有提到:參考 JavaScript 全攻略:克服 JS 的奇怪部分 - 執行環境與詞彙環境(1)
在Global Execution context 中會產生一個全域物件,叫做window,在全域環境中,他和this是相同的,this會指向window這個物件,你可以按下F12,在Console中輸入this,看看會印出什麼?
就是window
現在可以來看看程式碼
var person = {
firstname: 'John',
lastname: 'Doe',
getFullName: function() {
var fullname = this.firstname + ' ' + this.lastname;
return fullname;
}
}
我們可以知道,在getFullName中的this會指向person
接著再寫一段程式碼,我們想使用getFullName
var logName = function(lang1, lang2) {
console.log('Logged: ' + this.getFullName());
console.log('Arguments: ' + lang1 + ' ' + lang2);
console.log('-----------');
}
logName('Scott','Go');
這邊執行會報錯
主要是在這個function裡面,this是指向window,這樣我們要怎麼樣才能使用Person物件中的getFullName與property呢?
bind()
bind可以改變this的指向,在這邊我們是要使用Person物件中的getFullName,所以我們會這樣寫:
logName.bind(person)('Scott','Go');
注意:因為bind是原生function中的method,故我們的寫法會是functionName.bind(欲指向的物件),而我們為了要執行logName這個function,所以最後要加上()來執行,最後會跑出結果。
call()
call與bind一樣,它們唯一的差別在於call是改變this之後,會順便執行呼叫call的function
logName.call(person, 'Scott', 'Go');
apply()
同call也會直接執行,不同點在於定二個參數是吃array
logName.apply(person, ['Scott', 'Go']);
所以這三個寫法互為等價:
logName.bind(person,'Scott','Go')();
logName.call(person, 'Scott', 'Go');
logName.apply(person, ['Scott', 'Go']);
之後,講師做了一些延伸:提到兩個專有名詞function borrowing 與 function currying
function borrowing:
如下程式碼:
var person = {
firstname: 'John',
lastname: 'Doe',
getFullName: function() {
var fullname = this.firstname + ' ' + this.lastname;
return fullname;
}
}
var person2 = {
firstname: 'Jane',
lastname: 'Doe'
}
//function borrowing
console.log(person.getFullName.apply(person2));
person2想把自己的property丟到person中的getFullName去使用,就可以這樣寫,印出結果如下。
function currying
作者寫了一個multiply的function,但想讓a的值變成2,只留下參數b傳入,就可以這樣寫:
// function currying
function multiply(a, b) {
return a*b;
}
var multipleByTwo = multiply.bind(this, 2);
console.log(multipleByTwo(4));
這樣寫的好處是,每次用multipleByTwo這個function的時候,就不用重新設定第一個參數(因為已經設定好a=2)
其實function就很像這個樣子
function multiply(b) {
return 2*b;
}
這裡講到function currying的概念,有興趣可以看看這篇:連結
Curry 的概念很簡單:你可以只透過部分的參數呼叫一個 function,它會回傳一個 function 去處理剩下的參數。