為何是 this?
Why?使用 this,提供一個更優雅的方式來實作物件參考的傳遞,讓 API 的設計更乾淨、更易於重複使用。
容易混淆之處
它其實不是:自身 (Itself)、其範疇 (Its Scope)。
自身 (Itself)
function foo(num) { console.log( "foo: " + num ); // keep track of how many times `foo` is called this.count++; } foo.count = 0; var i; for (i=0; i<10; i++) { if (i > 5) { foo( i ); } } // foo: 6 // foo: 7 // foo: 8 // foo: 9 // how many times was `foo` called? console.log( foo.count ); // 0 -- WTF?
範例中由於 this 的指向不明確,因此實際上指到了全域。全域中建立了 count 變數,++後為 NaN。
迴避 this 的解法:
- 另外建立物件來持有特性
- 使用自身識別字
foo
取代 this
正確做法:使用 call()
將 this 指向 foo
本身。foo.call (foo, i);
。
其範疇 (Its Scope)
this 並沒有透過任何方式參考到一個函式的語彙範疇。
P.82 程式碼範例。
試著將程式碼展開,會發現 Scope 是在一樣的地方。
this 是什麼
this 是執行時期的繫結 (runtime binding),而非編寫時期 (author-time)。
this 繫結取決於函式被呼叫的方式。
當函式被調用時,會創建一個執行環境,並記錄呼叫堆疊 (call-stack),此紀錄的特性之一就是 this 參考,會在執行過程中被使用。
複習
- 要學好 this,首先得學會 this 不是什麼。
- this 是函式被呼叫時所進行的一個繫結,而它所參考到的是什麼,由呼叫地點 (call-site) 來決定。