摘要:關于中的指向我上的菜鳥倉庫地址點擊跳轉查看其他相關文章文章在我的博客上的地址點擊跳轉學習,必不可少的肯定要理解的指向。
關于javascript中this的指向
? ? ? ? 學習javascript,必不可少的肯定要理解this的指向。要學習this指向之前,就要先理解了我前面寫的幾篇文章,會更容易理解this的指向。
? ? ? ? 前面的文章說到, 執行上下文的創建階段,主要有三個內容:
? ? ? ? 1、創建變量對象;2、初始化作用域鏈;3、確定this的指向。
? ? ? ? 前兩個內容我都作了詳細的解析了,在這里,是時候要說一下第三個內容了,確定this的指向。其實this的指向從一些理論知識上理解,是很復雜的,看過不少文章都沒有說的很清楚,反而說得人懵逼了。其實,this的指向是非常簡單的,明確了它的規律,不要被太多代碼表達形式的改變而影響了正常的認識思維,那就可以了。
? ? ? ? 好了,來個普遍例子:
//全局環境 var a = 10; function inner(){ var a = 20; console.log(this.a); } inner();
? ? ? ? 當然了,打印結果是10,this就是指向全局對象。
? ? ? ? 好了,該解析this了,我們都知道this的指向是函數被調用的時候確定的。
? ? ? ? 簡單直接說結論:通過對象訪問屬性的方式執行函數,this就是指向這個對象,其他情況,嚴格模式下都是指向undefined,非嚴格模式下都是指向全局對象。
? ? ? ? 先解析上面例子,上面的inner函數是在全局環境中直接調用的:inner( ? ),大家可以理解這個調用,就是這一對方括號(),所以它是指向全局對象,所以this.a就是10。
//全局環境 var a = 10; var example = { a : 20, b : this.a + 10 } console.log(example.b);
? ? ? ? 打印結果是多少?30嗎?錯了,不是通過example這個對象訪問b屬性,所以b里面的this就是指向example嗎?錯了。
? ? ? ? 我說的是對象訪問屬性的方式執行函數,你這個b屬性內容不是函數。由于example是在全局環境中聲明的,所以里面的this就是指向全局對象,或者說,this的確定是函數被執行時候確定的,你的函數呢?往上找,就是全局對象這個大函數了,所以這個this就是指向全局對象。
? ? ? ? 當然了,如果你將example放進去某個函數里面,對照一下我的結論,就會知道這個this在嚴格模式下就會指向undefined,非嚴格模式就是指向全局對象。例子如下:
//非嚴格模式下的全局環境 var a = 10; function outer(){ var example = { a : 20, b : this.a + 10 } return example.b; } outer();//打印結果為20
//嚴格模式下的全局環境 "use strict" var a = 10; function outer(){ var example = { a : 20, b : this.a + 10 } return example.b; } outer();//執行會報錯,因為this指向undefined
? ? ? ? 還問為什么?因為outer函數被執行時候這個this才確定啊,而outer這個函數是多帶帶調用啊,直接outer( ?)這樣調用啊,所以就是結論中那樣啊。
? ? ? ? 好了,那怎樣是屬于對象訪問屬性的方式執行函數呢?再來例子:
//全局環境 var a = 10; var example = { a : 20, b : function(){ return this.a; } } console.log(example.b());
? ? ? ? 好了,這次打印結果是20了,因為通過了example訪問b屬性方式執行函數的,通過這個一點運算符的屬性訪問方式,叫做成員訪問。稍微改改再來例子:
//全局環境 var a = 10; var example = { a : 20, b : function(){ return this.a; } } var c = example.b; console.log(c());
? ? ? ? 還是20嗎?不是了,非嚴格模式是10,嚴格模式報錯(后面都是非嚴格模式的例子),因為調用函數c,前面只是通過example.b將函數的地址傳給了c而已,你調用函數時候,還是多帶帶調用啊。開始懂了對不對,再來例子:
//全局環境 var a = 10; function runAway(){ return this.a; } var example = { a : 20, b : runAway } console.log(example.b());
? ? ? ? 如果你不假思索就能說是20的話,證明你已邁出了一大步了,同一個道理,是通過對象訪問屬性的方式執行函數的,我管你的b屬性是直接指向函數,還是通過函數聲明指向函數的,反正你的this就是指向對象example。
? ? ? ? 好了,結合上面的再改一改例子:
//全局環境 var a = 10; function runAway(){ return this.a; } function worker(fn){ fn(); } var example = { a : 20, b : runAway } worker(example.b);
? ? ? ? 可能你會說,通過example.b這樣的的方式,我不管你有沒有跳出來的runAway,this肯定是指向example啦,那就要重溫一下我的結論了,我說的是通過對象訪問屬性的方式執行函數,你執行了嗎,你有一對方括號嗎?可能你會說,他們傳入去worker函數,里面就會加一對方括號執行啊,那就錯了。
? ? ? ? 通過這種方式的執行函數,其實已經變味了,這種情況和上面的例子:var c = example.b,然后c( )執行函數式一樣的,你只不過通過example.b將這個函數地址傳入了worker函數,然后執行而已。
? ? ? ? 所以上面這個例子,就是結論中的其他情況咯,嚴格模式this指向undefined(當然這個例子會報錯,因為undefined沒有a屬性),非嚴格模式指向全局對象(當然這個例子會打印undefined,因為全局對象沒有b屬性)。
? ? ? ? 好了,最后再舉一下其他例子:
//全局環境 var a = 10; var example = { a : 20, b : function(){ return this.a; } } //例子一 console.log(example.b()); //打印結果為20 //例子二 console.log((example.b)()); //打印結果為20 //例子三 console.log((false || example.b)()); //打印結果為10
? ? ? ? 好了,在例子一中,很清楚明白就是常規的this指向了example。
? ? ? ? 例子二中,你加了一個括號也沒用啊,我沒有將它的函數地址賦值其他什么變量啊,所以和例子一也是一樣的。
? ? ? ? 至于例子三,我們可以這樣理解,你在括號里面進行了一些其他運算,所以通過example.b這個方式只是拿了函數地址出來運算,所以在例子三中,括號的結果是example.b這個結果,所以是拿到了一個函數的地址,最后調用的時候還是多帶帶調用啊,就類似前面例子的worker函數那樣啊。
? ? ? ? 網上還有很多像例子三那樣的古靈精怪的例子,其實很簡單,你運算過了,最后出來的東西再加方括號調用,就是多帶帶調用了。
? ? ? ? 最后,好像忘了個很常用的構造函數的this指向:
//先來個構造函數Mankind function Mankind(name){ this.name = name; } //實例化對象Dad var Dad = new Mankind("BaBa"); console.log(Dad.name); //打印結果為BaBa
? ? ? ? 很明白了,通過構造函數實例化對象,構造函數里面的this就是指向這個實例化對象了。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/84529.html
摘要:閉包閉包是指有權訪問另一個函數作用域中的變量的函數當某個函數被調用時,會創建一個執行環境及相應的作用域鏈。要注意通過第句聲明的這個方法屬于構造函數生成的對象,而不屬于構造函數的變量對象,也就是說,并不存在于作用域鏈中。 看到評論里有仁兄建議我試試箭頭函數,真是受寵若驚,本來寫這篇文章也只是想記錄寫要點給自己日后看的。今天早上看到一篇總結javascript中this的文章JavaScr...
摘要:其實它們都很簡單,但是在處理一些與相關的函數的時候,用來改變函數中的指向,卻是必不可少的工具,所以必須掌握好它們的用法。 關于javascript中的bind、call、apply等函數的用法 我GitHub上的菜鳥倉庫地址: 點擊跳轉查看其他相關文章 文章在我的博客上的地址: 點擊跳轉 ? ? ? ? 前面的文章已經說到this的指向了,那么這篇文章就要說一說和this相關的三個...
摘要:函數的調用有五種模式方法調用模式,函數調用模式,構造器調用模式,調用模式以及回調模式,下面分別對這幾種模式進行說明。構造器調用模式構造函數的調用方式被稱為構造器調用模式,這是模擬類繼承式語言的一種調用方式。 函數的調用有五種模式:方法調用模式,函數調用模式,構造器調用模式,apply/call調用模式以及回調模式,下面分別對這幾種模式進行說明。 1.函數調用與方法調用模式: 1.1 聲...
摘要:關于提供了一種優雅的方式來隱式傳遞一個對象引用,因此可以將設計得更加簡潔并且易于復用。對于的誤解新手會誤認為指向函數本身。這時候,可以使用的方法強制使指向函數對象。的綁定和函數聲明的位置沒有任何關系,只取決于函數的調用方式。 關于this this 提供了一種優雅的方式來隱式傳遞一個對象引用,因此可以將API設計得更加簡潔并且易于復用。 /* *this 隱式傳遞...
摘要:當中的是一個用于指向當前上下文對象的關鍵字。創建實例時的構造函數中的,永遠指向那個實例后對象,不是外部環境使用來調用函數時,先改變其上下文環境,在對其構造函數進行調用。 javascript 當中的 this是一個用于指向當前上下文對象的關鍵字。在面向對象編程及日常開發當中我們經常與其打交道,初學javscript的朋友非常容易誤入歧途從而理解錯誤。 上下文對象概念 在我的深入貫徹閉包...
閱讀 972·2021-11-24 10:42
閱讀 3518·2021-11-19 11:34
閱讀 2654·2021-09-29 09:35
閱讀 2537·2021-09-09 09:33
閱讀 685·2021-07-26 23:38
閱讀 2527·2019-08-30 10:48
閱讀 1395·2019-08-28 18:07
閱讀 430·2019-08-26 13:44