JavaScript 跟你想得不一樣(二)
與其說跟你想得不一樣,還不如說是容易造成誤解吧。
到底 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 一定要很小心啊啊啊~
歷史上的今天
- Android Platform Open Source - 2008
- 日本關東行 Day 4 — 海不辭水,故能成其大 - 2007
- Flickr 即將加入相片編輯功能 - 2007
- 該來的還是來了 - 2006

嗚嗚 深有同感 。。。。
傻傻分不清楚
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!