原文:http://www.cnblogs.com/wangfupeng1988/p/3988422.htmljavascript
接着上一節講的話,應該輪到「執行上下文棧」了,可是這裏不得不插入一節,把this說一下。由於this很重要,js的面試題若是不出幾個與this有關的,那出題者都不合格。html
其實,this的取值,分四種狀況。咱們來挨個看一下。前端
在此再強調一遍一個很是重要的知識點:在函數中this到底取何值,是在函數真正被調用執行的時候肯定的,函數定義的時候肯定不了。由於this的取值是執行上下文環境的一部分,每次調用函數,都會產生一個新的執行上下文環境。java
狀況1:構造函數web
所謂構造函數就是用來new對象的函數。其實嚴格來講,全部的函數均可以new一個對象,可是有些函數的定義是爲了new一個對象,而有些函數則不是。另外注意,構造函數的函數名第一個字母大寫(規則約定)。例如:Object、Array、Function等。面試
以上代碼中,若是函數做爲構造函數用,那麼其中的this就表明它即將new出來的對象。json
注意,以上僅限new Foo()的狀況,即Foo函數做爲構造函數的狀況。若是直接調用Foo函數,而不是new Foo(),狀況就大不同了。閉包
這種狀況下this是window,咱們後文中會說到。app
狀況2:函數做爲對象的一個屬性函數
若是函數做爲對象的一個屬性時,而且做爲對象的一個屬性被調用時,函數中的this指向該對象。
以上代碼中,fn不只做爲一個對象的一個屬性,並且的確是做爲對象的一個屬性被調用。結果this就是obj對象。
注意,若是fn函數不做爲obj的一個屬性被調用,會是什麼結果呢?
如上代碼,若是fn函數被賦值到了另外一個變量中,並無做爲obj的一個屬性被調用,那麼this的值就是window,this.x爲undefined。
狀況3:函數用call或者apply調用
當一個函數被call和apply調用時,this的值就取傳入的對象的值。至於call和apply如何使用,不會的朋友能夠去查查其餘資料,本系列教程不作講解。
狀況4:全局 & 調用普通函數
在全局環境下,this永遠是window,這個應該沒有非議。
普通函數在調用時,其中的this也都是window。
以上代碼很好理解。
不過下面的狀況你須要注意一下:
函數f雖然是在obj.fn內部定義的,可是它仍然是一個普通的函數,this仍然指向window。
完了。
看到了吧,this有關的知識點仍是挺多的,不只多並且很是重要。
最後,既然提到了this,有必要把一個很是經典的案例介紹給你們,又是jQuery源碼的。
以上代碼是從jQuery中摘除來的部分代碼。jQuery.extend和jQuery.fn.extend都指向了同一個函數,可是當執行時,函數中的this是不同的。
執行jQuery.extend(…)時,this指向jQuery;執行jQuery.fn.extend(…)時,this指向jQuery.fn。
這樣就巧妙的將一段代碼同時共享給兩個功能使用,更加符合設計原則。
好了,聊完了this。接着上一節繼續說「執行上下文棧」。
注意:還有一部分this的內容本文中沒有講到,已經補充到這裏:http://www.cnblogs.com/wangfupeng1988/p/3996037.html
---------------------------------------------------------------------------
本文已更新到《深刻理解javascript原型和閉包系列》的目錄,更多內容可參見《深刻理解javascript原型和閉包系列》。
另外,歡迎關注個人微博。
也歡迎關注個人其餘教程:
《用grunt搭建自動化的web前端開發環境》《從設計到模式》《json2.js源碼解讀視頻》《微軟petshop4.0源碼解讀視頻》
--------------------------------------------------------------------------