Javascript 的 `this` 是指什麼?
我們之前談過 scopes 和 closures. this 指的是當下這個 scope 的物件. 在瀏覽器裡最上層 scope 的物件是 window. 在 node.js 裡最上層是 global objects.
Javascript 是一個很自由的語言. 你可以用 functional programming 或者是 object oriented programming 的方式來撰寫. 用 functional programming 寫法通常是變數和 callbacks 傳來傳去, 用 closure 來存資料. this 通常用不太到. 但是 OOP 方式來撰寫的話就是一定要用到 this 了.
因為基本上這是一個 node.js 的教學, 所以我不會題太多 this 在 browser 端該如何運作. 從下面的範例裡我們可以看一下 this 和之前提到的 scope 有什麼關係.
var something, another;
something = {
x : 'x',
print : function( callback ){
callback && callback.call( this );
console.log( this.x );
}
};
another = {
x : 'a',
set_x : function(){
this.x = 'b';
}
};
// situation a
something.print( function(){
another.set_x();
});
// situation b
something.print( another.set_x );
// situation c
something.print( function(){
another.set_x.call( this );
});
結果
x b b
所以為何在 situation b 可以用 another 來設定 something 裡面的 x 呢? 那是因為我們在 something 的 print method 裡用了 call 並帶入了一個參數 this. 這樣一來 something 和 callback 就是屬於同一個 scope. 在 situation a 我們傳入了一個匿名函式當作 callback 並在這個匿名函式裡面呼叫 another.set_x. 因為一個 function 就會產生一個新的 scope. 所以 callback 裡的 this 指到的不是 another 而是那個匿名函式. 要讓他正常運作的話只要像 situation c 一樣在匿名函式裡再用 call 一次來讓匿名函式和 another 屬於同一個 scope 就可以了.
常見錯誤
有一種常見的錯誤是當我們想在不同 scope 裡使用 this, 而 this 卻指向不是我們要的 object. 所以我們呼叫的函式或是 property 常常會變成 undefined. 這時只要在上層的 scope 裡把 this 指向一個變數, 舉例來說 self. 這樣就可以在不同的 scope 裡來用 self 來代替 this 了.
var example = {
name : 'who',
wrong : function(){
setTimeout( function(){
console.log( this.name );
}, 0 );
},
right : function(){
var self = this;
setTimeout( function(){
console.log( self.name );
}, 0 );
}
};
example.wrong();
example.right();
結果
undefined who
這篇文章 Javascript call 以及 apply 有比較深入的介紹.




