上一章咱們講了關於做用域和閉包的相關知識,如今開始新一輪的學習,那就是JavaScript中最複雜的機制之一---this關鍵字。它是一個很特別的關鍵字,被自動定義在全部函數的做用域中。另外咱們須要明確的一點就是,this在任何狀況下都不指向函數的詞法做用域。數組
那麼咱們來看看this究竟是怎麼樣的機制。this是在運行時進行綁定的,它的上下文取決於函數調用時的各類條件。另外,this的綁定和函數聲明的位置沒有任何關係,之取決於函數的調用方式。閉包
默認綁定就是最經常使用的獨立函數調用時所綁定的。思考一下代碼app
function foo() { console.log(this.a); } var a = 2; foo(); // 2
咱們能夠看到,當調用foo()
時,this.a
被解析成了全局變量a。
可是,若是使用嚴格模式,那麼就不能將全局對象用於默認綁定,報錯TypeError:this is undefined
函數
一個對那個內部包含一個指向函數的屬性,並經過這個屬性間接引用函數,從而把this隱式綁定到這個對象上。因此這一條就須要考慮調用位置是否有上下文對象。學習
function foo() { console.log(this.a); } var obj = { a : 2, foo: foo }; obj.foo(); // 2
這段代碼中,當foo()
被調用時,前面加上了對obj
的引用。當函數引用有上下文對象時,隱式綁定規則會把函數調用中的this綁定到這個上下文對象。另外,對象屬性引用鏈中只有上一層或者說最後一層在調用位置中起做用。也就是說,this永遠都是指向最近調用的位置。this
前面說了隱式綁定的概念,那麼咱們若是不想在對象內部包含函數引用,而想在某個對象上強制調用函數,該如何作呢?
JavaScript中提供了兩個方法,分別是call()
和apply()
,那麼咱們應該怎麼在實際中運用呢?
首先咱們要搞清楚call()
和apply()
的做用,這裏引用MDN上的解釋:prototype
call() 方法調用一個函數, 其具備一個指定的this值和分別地提供的參數(參數的列表)。
apply() 方法調用一個具備給定this值的函數,以及做爲一個數組(或相似數組對象)提供的參數。
具體如何實現,這裏不做展開說明,能夠自行研究,加深理解。code
能夠看出,它們倆的差別僅在於所需參數的形式不一樣,ok迴歸正題。
請看下面代碼:對象
function foo() { console.log(a); } var obj = { a: 2 } foo.call(obj); // 2
這樣,咱們就能夠在調用foo的時候強制把它的this綁定到obj上ip
在傳統的面向類語言中,使用new初始化類時會調用類中的構造函數。可是,JavaScript中的構造函數只是使用new
操做符時被調用的函數。它們並不屬於某個類,也不會實例化一個類。
JavaScript中使用new調用函數時,會自動執行下面操做
那麼咱們在判斷函數在某個調用位置應該應用哪條規則呢,優先級如何判斷呢?有下面四條法寶供參考
new
中調用?若是是,則this綁定的是新對象固然,也許會有例外的狀況發生,暫時先留着,你們一塊兒思考一下,看看會在什麼狀況下出現這種例外狀況。
那麼,今天就先到這裏啦
see u ~ again