Update: MDN的文檔中關於該問題有更權威的解釋 ? DOM事件處理函數中的 this 《權威指南》中文版455頁關於這個問題也有說明,而且提到:IE9以前的attachEvent()
做爲函數調用其this
值是全局(window)對象。
當時想這問題的時候沒去找文檔,書也沒看仔細啊!
使用JS原型封裝對象的時候,綁定事件我有時會這樣寫:函數
var obj = function() {...} // 將某事件綁定至某對象e,但事件函數中上下文保持爲obj obj.prototype.bindEvn = function(e){ e.addEventListener(Event,obj.method.bind(this),false) } obj.prototype.method = function(){...}
這裏addEventListener中this的指向我不是太清晰, 雖然一直以來都直接用bind設置this的值(毫無疑問地返回了一個綁定了obj對象的函數),可是若是沒用bind方法會是種什麼狀況? 這裏面的this指向是調用addEventListener方法的對象e呢仍是obj(若是這樣那麼我這bind白用了?)
立刻作個demo看下到底啥狀況:
我是DEMO
(貌似demo設計得有點略傻?)this
//定義一個可見的盒子用於綁定點擊事件 var box = document.getElementById('box'); box.x = 'box' //設置執行函數的對象屬性 function outFunc() { this.x = 'outFunc'; box.addEventListener('click', func, false); } outFunc(); function func() { console.log(this.x); //輸出box 說明該this指向的是調用addEventListener的對象 }
當用bind設置this值的時候, this才指向執行函數prototype
function outFunc() { this.x = 'outFunc';//給全局對象window.x賦值(至關於賦值全局變量) box.addEventListener('click', func.bind(this), false); } function func() { console.log(this.x); //輸出outFunc 使用bind設置this的值 }
其實這裏面也涉及到了JS的基本概念, 也就是當函數做爲方法調用時,this指向調用該方法的對象, 當函數做爲嵌套函數調用時, this指向全局對象(非嚴格模式下)或者undefined(嚴格模式)而不是其外包函數的上下文, 若是對這個概念認識清楚了,就能夠發現addEventListener的中的事件函數默認是做爲調用addEventListener對象的方法,若是須要設置this的指向(好比上面的栗子中就使用bind設置this的指向爲外包函數的上下文),則能夠使用bind()。設計
這種狀況和內聯函數中的this指向相似,當this被內聯函數調用時,它的this默認指向監聽器所在的DOM元素。這裏直接用MDN文檔中的栗子:code
<button onclick="alert(this.tagName.toLowerCase());"> Show this </button> //輸出button
在stackoverflow上也有相似問題的討論:
The value of 「this」 within the handler using addEventListener
關於this值的問題,要多看看MDN的文檔:
this對象
本身動手,豐衣足食,吃早餐去了~事件