Note - 重新認識javascript (6)
更新時間: 2021/12/17
this
this是 JavaScript 的一個關鍵字this是 function 執行時,自動生成的一個內部物件- 隨著 function 執行場合的不同,
this所指向的值,也會有所不同 - 在大多數的情況下,
this代表的就是呼叫 function 的物件 (Owner Object of the function)
const getName = function() {
return this.name;
}
const bunny1 = {
name: 'yuan',
getName: getName
}
const bunny2 = {
name: 'bao fen',
getName: getName
}
console.log(bunny1.getName()); // yuan
console.log(bunny2.getName()); // bao fen
this 不等於 function
var foo = function() {
// 此時的this是window,因此this.count++的結果為NaN
this.count++;
};
foo.count = 0;
for( var i = 0; i < 5; i++ ) {
foo();
}
console.log(foo.count) // 0
var bar = function() {
// 此時的this是window
console.log( this.a );
};
var foo = function() {
var a = 123;
this.bar();
};
foo(); // undefined
巢狀迴圈中的 this
- JavaScript 中,用來切分變數的最小作用範圍 (scope) 是
function - 當
沒有特定指明this 的情況下,預設綁定 (Default Binding) this 為「全域物件」,也就是window
var obj = {
func1: function(){
// 因為func1是被obj呼叫,因此這時候的this是obj本身
console.log( this === obj ); // true
var func2 = function(){
// 此時的this會是window
console.log( this === obj ); // false
};
func2();
}
};
obj.func1();
強制指定 this 的方式
- 強制指定 this 的方式,分別是
call()、apply()以及bind()
var bunny = {
name: 'yuan',
age: 10
};
var getAge = function () {
console.log(this.age);
};
getAge(); // undefined
getAge.bind(bunny)(); // 10
.call()與.apply()的作用完全一樣,差別只在傳入參數的方式有所不同:
function func( arg1, arg2, ... ){
// do something
}
func.call( context, arg1, arg2, ... );
func.apply( context, [ arg1, arg2, ... ]);
bind()讓 function 在呼叫前先綁定某個物件,使它不管怎麼被呼叫都能有固定的this.call()與.apply()是使用在 context較常變動的場景,依照呼叫時的需要帶入不同的物件作為該 function 的 this,在呼叫的當下就立即執行
this 與前後文本 (context) 綁定的基本原則
- 預設綁定 (Default Binding)
- 當 function 是在普通、未經修飾的情況下被呼叫,此時裡面的
this會自動指定至全域物件 - 若是加上
"use strict"宣告成嚴格模式後,原本預設將this綁定至全域物件的行爲,會轉變成undefined
- 當 function 是在普通、未經修飾的情況下被呼叫,此時裡面的
- 隱含式綁定 (Implicit Binding)
- 即使 function 被宣告的地方是在
global scope中,只要它成為某個物件的參考屬性(reference property),在那個 function 被呼叫的當下,該 function 即被那個物件所包含
function func() { console.log( this.a ); } var obj = { a: 2, foo: func }; obj.foo(); // 2 var func2 = obj.foo; func2(); // undefined - 即使 function 被宣告的地方是在
- 顯式綁定 (Explicit Binding)
- 透過
.bind()/.call()/.apply()這類直接指定this 的 function
- 透過
- 「new」關鍵字綁定
function foo(a) { this.a = a; } var obj = new foo( 123 ); console.log( obj.a ); // 123
歸納 this
- function是被
new出來的 ---> this 是被建構出來的物件 - function是以
.call()/.apply()/.bind()呼叫 ---> this 是被指定的物件 - function
被呼叫時存在於物件---> this 是那個物件 - others ---> this 是
window,嚴格模式下是undefined