記錄本身認識的this => JavaScript

對於JavaScript 開發者來講,this 的綁定一直是一件很是使人困惑的事。函數

this 是很是重要的,可是猜想、嘗試並出錯和盲目地從 Stack Overflow上覆制和粘貼答案並不能讓你真正理解 this 的機制。oop

首先得明白this既不指向函數自身也不指向函數的詞法做用域,你也許被這樣的解釋誤導過,但其實它們都是錯誤的ui

this 其實是在函數被調用時發生的綁定,它指向什麼徹底取決於函數在哪裏被調用。this

// 默認綁定 => 在代碼中,foo() 是直接使用不帶任何修飾的函數引用進行調用的
// 函數調用時應用了 this 的默認綁定,所以 this 指向全局對象
function foo() {
    console.log( this.a );
}
var a = 2;
foo(); // 2

// 隱式綁定
// 當 foo() 被調用時,它的落腳點確實指向 obj 對象
// 當函數引用有上下文對象時,隱式綁定規則會把函數調用中的 this 綁定到這個上下文對象
// 由於調用 foo() 時 this 被綁定到 obj,所以 this.a 和 obj.a 是同樣的
function foo() {
    console.log( this.a );
}
var obj = {
    a: 2,
    foo: foo
};
obj.foo(); // 2

// 對象屬性引用鏈中只有最頂層或者說最後一層會影響調用位置。舉例來講:
function foo() {
    console.log( this.a );
}
var obj2 = {
    a: 42,
    foo: foo
};
var obj1 = {
    a: 2,
    obj2: obj2
};
obj1.obj2.foo(); // 42

//**隱式丟失**
// 雖然 bar 是 obj.foo 的一個引用,可是實際上,它引用的是 foo 函數自己,
// 所以此時的bar() 實際上是一個不帶任何修飾的函數調用,所以應用了默認綁定
function foo() {
	console.log( this.a );
}
var obj = {
	a: 2,
	foo: foo
};
var bar = obj.foo;
var a = "oops, global";
bar(); // oops, global

// 一種更微妙、更常見而且更出乎意料的狀況發生在傳入回調函數時:
function foo() {
    console.log( this.a );
}
function doFoo(fn) {
    // fn 其實引用的是 foo
    fn(); // <-- 調用位置!
}
var obj = {
    a: 2,
    foo: foo
};
var a = "oops, global"; // a 是全局對象的屬性
doFoo( obj.foo ); // "oops, global"
//參數傳遞其實就是一種隱式賦值,所以咱們傳入函數時也會被隱式賦值,因此結果和上一個例子同樣
複製代碼

今天記錄就到此結束,下次繼續^_^spa

相關文章
相關標籤/搜索