關於this
this 提供了一種優雅的方式來隱式「傳遞」一個對象引用,所以能夠將API設計得更加簡潔而且易於複用。
/*
*this 隱式傳遞上下文對象
*/
function identify() {
return this.name.toUpperCase();
}
function speak() {
var greeting = "Hello, I am " + identify.call(this);
console.log(greeting);
}
var me = {
name: "kelly"
}
var you = {
name: "lucy"
}
identify.call(me); //KELLY
identify.call(you); //LUCY
speak.call(me); //Hello, I am KELLY
speak.call(you); //Hello, I am LUCY
隨着使用模式愈來愈複雜,顯式傳遞上下文對象會讓代碼變得愈來愈亂,使用this則不會這樣。
對於this的誤解
新手會誤認爲this指向函數自己。
/*
*關於this的誤解
*/
function foo(num) {
console.log("foo: " + num);
this.count++;
}
foo.count = 0;
var i;
for (i = 0; i < 10; i++) {
if (i > 5) {
foo(i);
}
}
console.log(foo.count); //0
因而可知,瀏覽器解析語句產生了4條輸出,證實foo(...)確實被調用了4次,可是foo.count仍然是0,顯然從字面意思來理解this是錯誤的。
這時候,可使用Function.call()的方法強制使this指向foo函數對象。
/*
*使用function.call()方法使this指向foo函數對象。
*/
function foo(num) {
console.log("foo: " + num);
this.count++;
}
foo.count = 0;
for (i = 0; i < 10; i++) {
if (i > 5) {
foo.call(foo, i)
}
}
console.log(foo.count);
this 究竟是什麼
this是在運行時進行綁定的,並非在編寫時綁定,它的上下文取決於函數調用時的各類條件。this的綁定和函數聲明的位置沒有任何關係,只取決於函數的調用方式。
當一個函數被調用時,會建立一個活動記錄。這個記錄會包含函數在哪裏被調用、函數的調用方式、傳入的參數等信息。this就是這個記錄的一個屬性,會在函數執行的過程當中用到。
小結
學習this的第一步是明白this既不指向函數自身也不指向函數的詞法做用域,拋開之前錯誤的假設和理解。
this其實是在函數被調用時發生的綁定,它指向什麼徹底取決於函數在哪裏被調用。