天天看點

詳解JavaScript中的this

javascript中的this總是讓人迷惑,應該是js衆所周知的坑之一。 個人也覺得js中的this不是一個好的設計,由于this晚綁定的特性,它可以是全局對象,目前對象,或者…有人甚至因為坑大而不用this。

其實如果完全掌握了this的工作原理,自然就不會走進這些坑。來看下以下這些情況中的this分别會指向什麼:

全局範圍内的this将會指向全局對象,在浏覽器中即使window。

這裡this指向了全局對象,即window。在嚴格模式中,則是undefined。

輸出 foocoder says hello world。this指向person對象,即目前對象。

函數内部的this指向新建立的對象。

在内部函數中,this沒有按預想的綁定到外層函數對象上,而是綁定到了全局對象。這裡普遍被認為是javascript語言的設計錯誤,因為沒有人想讓内部函數中的this指向全局對象。一般的處理方式是将this作為變量儲存下來,一般約定為that或者self:

apply和call類似,隻是後面的參數是通過一個數組傳入,而不是分開傳入。兩者的方法定義:

兩者都是将某個函數綁定到某個具體對象上使用,自然此時的this會被顯式的設定為第一個參數。

<a target="_blank"></a>

簡單地總結以上幾點,可以發現,其實隻有第六點是讓人疑惑的。

其實就可以總結為以下幾點:

1.當函數作為對象的方法調用時,this指向該對象。

2.當函數作為淡出函數調用時,this指向全局對象(嚴格模式時,為undefined)

3.構造函數中的this指向新建立的對象

4.嵌套函數中的this不會繼承上層函數的this,如果需要,可以用一個變量儲存上層函數的this。

再總結的簡單點,如果在函數中使用了this,隻有在該函數直接被某對象調用時,該this才指向該對象。

我們可能經常會寫這樣的代碼:

如果在handler中用了this,this會綁定在obj上麼?顯然不是,指派以後,函數是在回調中執行的,this會綁定到$(“#some-div”)元素上。這就需要了解函數的執行環境。本文不打算長篇贅述函數的執行環境,可以參考《javascript進階程式設計》中對執行環境和作用域鍊的相關介紹。這裡要指出的時,了解js函數的執行環境,會更好地了解this。

那我們如何能解決回調函數綁定的問題?es5中引入了一個新的方法,bind():

該方法建立一個新函數,稱為綁定函數,綁定函數會以建立它時傳入bind方法的第一個參數作為this,傳入bind方法的第二個以及以後的參數加上綁定函數運作時本身的參數按照順序作為原函數的參數來調用原函數.

顯然bind方法可以很好地解決上述問題。

其實該方法也很容易模拟,我們看下prototype.js中bind方法的源碼:

明白了麼?

相信看完全文以後,this不再是坑~

 <b>原文釋出時間為:2013-05-10</b>

<b>本文來自雲栖社群合作夥伴“linux中國”</b>