JavaScript 語言核心(11)this 是什麼?
JavaScript 語言核心(10)初探一級函式 << 前情 在 JavaScript 中,函式是物件,是 function toString() { return '[' + this.name + ',' + this.age + ']'; } var p1 = { name : 'Justin', age : 35, toString : toString }; var p2 = { name : 'momor', age : 32, toString : toString }; console.log(p1.toString()); // [Justin,35] console.log(p2.toString()); // [momor,32] 在上例中定義了一個 在上例中, 如果呼叫函式時是透過物件與點運算子的方式呼叫,則 在 JavaScript 中,函式是 function toString() { return '[' + this.name + ',' + this.age + ']'; } var p1 = { name : 'Justin', age : 35, }; var p2 = { name : 'momor', age : 32, }; console.log(toString.call(p1)); // [Justin,35] console.log(toString.call(p2)); // [momor,32] 這次並沒有將 function add(num1, num2) { return this.num + num1 + num2; } var o = {num : 10}; console.log(add.call(o, 20, 30)); // 60
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)); // 60 console.log(add.apply(o2, args)); // 150 所以, function toString() { return this.name; } var p1 = { name : 'Justin', toString : toString }; var p2 = { name : 'momor', toString : toString }; console.log(p1.toString()); // Justin console.log(p2.toString()); // momor console.log(p1.toString.call(p2)); // momor 在最後一個測試中,是以 在用物件實字建立物件時,也可以直接指定函式作為特性。例如: var o = { name : 'Justin', toString : function() { return this.name; } }; console.log(o.toString()); // Justin 如果呼叫函式時,無法透過 全域物件是 JavaScript 執行時期全域可見的物件,在不同的環境中想要取得全域物件,會透過不同的名稱,像是 Node.js 中可以使用 因此,如果你想統一全域物件的變數名稱,例如統一使用 var global = global || (function() { return this; })(); 類似地,非嚴格模式下,當一個內部函式直接被呼叫時,無法確定 function func() { function inner() { return this; } return inner(); } console.log(func() === global); // true var o1 = {func : func}; console.log(o1.func() === o1); // false console.log(o1.func() === global); // true console.log(func.call(o1) === global); // true 在上例中,最後一個例子雖然指定外部函式的 function func() { function inner() { return this; } this.inner = inner; return this.inner(); } console.log(func() === global); // true var o1 = {func : func}; console.log(o1.func() === o1); // true console.log(o1.func.call(global) === global); // true console.log(func.call(o1) === global); // false 然而,在無法確立 'use strict' (function() { return this; })(); // undefined 在嚴格模式下,如果真的想取得全域物件,可以透過兩個方式,第一個是直接建立 var global = global || Function('return this')(); 第二個方式是間接參考 var get = eval; var global = global || get('this'); 詳情可以參考 How to get the global object in JavaScript?,如果不想多個 var global = global || (0, eval)('this'); 這個有趣的語法在於,逗號運算子會從左而右運算每個運算元,然後傳回最後一個運算元,可參考 MDN:Comma operator 的說明。 在 JavaScript 執行過程中,搞清楚 舉個例子來說,如果你想要自行實現 var obj = { '0' : 100, '1' : 200, '2' : 300, length : 3, forEach : function(callback) { for(var i = 0; i < this.length; i++) { callback(this[i]); } } }; obj.forEach(function(elem) { console.log(elem); }); 在上例中,由於呼叫 在 ECMAScript 5 中,函式實例有個 function forEach(callback) { for(var i = 0; i < this.length; i++) { callback(this[i]); } } var obj1 = { '0' : 100, '1' : 200, '2' : 300, length : 3, }; var f1 = forEach.bind(obj1); f1(function(elem) { console.log(elem); // 100 200 300 }); var obj2 = { '0' : 10, '1' : 20, '2' : 30, length : 3, forEach : f1 }; obj2.forEach(function(elem) { console.log(elem); // 100 200 300 }); 在上面這個例子中,即使後來透過
function plus(a, b) { return a + b; } var addTwo = plus.bind(undefined, 2); console.log(addTwo(10)); // 12 console.log(addTwo(5)); // 7 |