call可以讓你決定this的參考對象
在 JavaScript 中,函式是 Function 的實例,Function 都會有個 call 方法,可以讓你決定 this 的參考對象。舉例來說,你可以如下呼叫:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| function toString(){ return '[' + this.name + ',' + this.age + ','; }
var p1 = { name:'Justin', age :35 };
var p2 = { name : 'momor', age : 32 };
console.log( toString.call(p1) ); console.log( toString.call(p2) );
|
妳可以覆寫call方法,讓this參考別的物件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function toString() { return this.name; }
var p1 = { name : 'Justin', toString : toString };
var p2 = { name : 'momor', toString : toString };
console.log(p1.toString()); console.log(p2.toString()); console.log(p1.toString.call(p2));
|
當call遇到有參數的函式時
call 方法的第一個參數就是用來指定函式中的 this 所參考的物件。如果函式原本具有參數,則可接續在第一個參數之後。例如:
1 2 3 4 5 6 7
| function add(num1, num2) { return this.num + num1 + num2; }
var o = {num : 10};
console.log(add.call(o, 20, 30));
|
同樣決定this的參考對象還有apply可以使用決定
差別在於apply必須將引數蒐集起成陣列,做為第二個參數來呼叫函數。
1 2 3 4 5 6 7 8 9 10
| function add(num1, num2) { return this.num + num1 + num2; }
var o1 = {num : 10}; var o2 = {num : 100}; var args = [20, 30];
console.log(add.apply(o1, args)); console.log(add.apply(o2, args));
|
this與全域物件
如果呼叫函式時,無法透過 . 運算、call、apply 等方法確定 this 的對象,如果不是嚴格模式,那麼 this 會直接轉為參考全域物件(Global object)。
全域物件是 JavaScript 執行時期全域可見的物件,在不同的環境中想要取得全域物件,會透過不同的名稱,像是 Node.js 中可以使用 global,瀏覽器中可以透過 window 或在全域範圍使用 this,Rhino(或 JDK8 的 Nashorn)可以在全域範圍使用 this 取得。
因此,如果你想統一全域物件的變數名稱,例如統一使用 global,可以透過類似以下的方式:
1 2 3
| var global = global || (function() { return this; })();
|
this參考的對象並非以附屬在哪個物件而定
this 實際參考的對象,是以呼叫方式而定,而不是它是否附屬在哪個物件而定。例如就算函式是附屬在函式上的某個特性,也可以這麼改變 this 所參考的對象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function toString() { return this.name; }
var p1 = { name: 'Justin', toString: toString };
var p2 = { name: 'momor', toString: toString };
console.log(p1.toString()); console.log(p2.toString()); console.log(p1.toString.call(p2));
|
參考資料 & 延伸閱讀