與其說跟你想得不一樣,還不如說是容易造成誤解吧。
到底 this 是誰?
JavaScript 的 code 寫多了,你一定會碰到 this
這個關鍵字,是某個 object 下的 method 也好,或是 callback function 也好,關於 this
的用法常常會讓人搞混。
以一句簡單的話來說:在 function 裡,this
所代表的就是呼叫這個 function 的東西。
以下面這段程式碼為例,onButtonClick
是一個處理按鈕被按下時的 callback function:
var button = document.getElementById('foo');
var onButtonClick = function(evt) {
alert(this);
};
if (button.addEventListener) {
button.addEventListener('click', onButtonClick, false);
} else {
button.attachEvent('onclick', onButtonClick);
}
上面這段 code 分別為了 non-IE 及 IE 瀏覽器不同的註冊 event handler 的寫法來操作,你可以發現,當你在 non-IE 的瀏覽器上執行這段程式碼,當按鈕按下時,訊息視窗應該會跳出有 HTMLInputElement
的訊息,表示呼叫這個 callback function 的物件就是 button
,然而,在 IE 底下,你看到的則是 Window
。雖然有這樣的不同,但至少有一件事是一致的:this
代表的就是 caller
至於一般的 function,「沒指定的話」都是 window
,注意我這裡強調是「沒指定」,所以這也就代表了「可以指定」,以下面這段程式碼為例:
var foo = function(x) {
alert(x);
alert(this);
}
foo('abc');
你應該會看到訊息視窗先顯示 abc
,接著就是顯示出 window
。但若是變成下面這樣呢?
var foo = function() {
alert(arguments[0]);
alert(this.name);
}
var bar = { name: 'bar' };
foo.apply(bar, ['abc']);
在呼叫 foo
函式時使用 apply
方法,就可以更換 caller(正確地說是切換 context),而因為用了 apply
方法,函式的參數就要改以陣列傳入。當然,這時候的 this
就變成了 bar
…..
簡單地結論就是….要在 function 裡使用 this
一定要很小心啊啊啊~
嗚嗚 深有同感 。。。。
傻傻分不清楚
foo.call(bar, ‘abc’);
yes, call method is another way to change the context.
抱歉 剛剛是用手機打的 沒法打太多字
用 call 就不用傳陣列了 foo.call(bar, ‘abc’);
https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference:Global_Objects:Function:call
apply 一般是搭配 arguments 使用 所以才寫成陣列 foo.apply(bar, arguments);
https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Using_the_arguments_object
Good article!