国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

理解JavaScript的核心知識點:This

TerryCai / 2762人閱讀

摘要:關(guān)鍵字計算為當(dāng)前執(zhí)行上下文的屬性的值。毫無疑問它將指向了這個前置的對象。構(gòu)造函數(shù)也是同理。嚴(yán)格模式無論調(diào)用位置,只取顯式給定的上下文綁定的,通過方法傳入的第一參數(shù),否則是。其實并不屬于特殊規(guī)則,是由于各種事件監(jiān)聽定義方式本身造成的。

thisJavaScript 中非常重要且使用最廣的一個關(guān)鍵字,它的值指向了一個對象的引用。這個引用的結(jié)果非常容易引起開發(fā)者的誤判,所以必須對這個關(guān)鍵字刨根問底。

執(zhí)行上下文:Execution Context

在深入了解 this 對象之前先介紹另一個概念:執(zhí)行上下文。

沒錯,執(zhí)行上下文與 this 在本質(zhì)上是兩個概念,或者說它們指代的范疇有差異,想要準(zhǔn)確認(rèn)識 this,就得先把它們區(qū)分開。

可以把執(zhí)行上下文想象為一個容器,其中包含了一句句待執(zhí)行的代碼。代碼在這個容器中有上下行兩條路線,是由某一些特殊代碼所觸發(fā)(如函數(shù)),上行路線跳入了一個新的容器,開始在新容器中執(zhí)行另一些代碼,本容器中的后續(xù)代碼被暫時中斷;如果新容器中還有代碼會觸發(fā)上行路線,就繼續(xù)往上增加新容器,并交出控制權(quán),層層疊加,形成了一個從底往上形式的疊羅漢,這就是 JavaScript 運行時的執(zhí)行上下文棧。

執(zhí)行上下文這一抽象概念本身包含了更多有關(guān) JavaScript 這門語言的內(nèi)部機制,對于語言使用者來說是不透明的,其中與運行前的編譯規(guī)則有很大關(guān)聯(lián),并被包含到整個程序運行前的初始化過程中,與詞法作用域的變量解析規(guī)則相配合,將這些靜態(tài)解析后的變量帶入運行時的環(huán)境,所以它是程序運行時的關(guān)鍵內(nèi)部組件或者說容器,而 JavaScript 將對執(zhí)行上下文的引用提供給程序開發(fā)者的唯一入口就是 this,它得以訪問被編譯后帶入到某個執(zhí)行上下文運行環(huán)境中的變量。this 指代的其實只是內(nèi)部抽象的執(zhí)行上下文向用戶所開放的那一部分,其實體是一個對象,綁定了許多編譯后的變量。

以下是一段關(guān)于執(zhí)行上下文精辟的總結(jié):

An execution context is purely a specification mechanism and need not correspond to any particular artefact of an ECMAScript implementation. It is impossible for ECMAScript code to directly access or observe an execution context.

翻譯:執(zhí)行上下文純粹是一種規(guī)范機制,它不需要與基于 ECMAScript 規(guī)范的任何特定擴展實現(xiàn)對應(yīng)。ECMAScript 代碼無法直接訪問或觀察執(zhí)行上下文。

關(guān)于This對象:What"s This

我將官方文檔和一些別的文章里的說明稍加梳理,可以從以下段落中較為清晰地看出 this 的本質(zhì):

First, know that all functions in JavaScript have properties, just as objects have properties. And when a function executes, it gets the this property—a variable with the value of the object that invokes the function where this is used.

The this keyword evaluates to the value of the ThisBinding of the current execution context.

The abstract operation GetThisEnvironment finds the Environment Record that currently supplies the binding of the keyword this

this is not assigned a value until an object invokes the function where this is defined.

翻譯:

首先,要知道 JavaScript 中所有的函數(shù)與對象一樣都擁有屬性。當(dāng)一個函數(shù)執(zhí)行時,它得到 this 屬性——一個指向調(diào)用函數(shù)的對象的變量。

this 關(guān)鍵字計算為當(dāng)前執(zhí)行上下文的 ThisBinding 屬性的值。

GetThisEnvironment 抽象運算查找當(dāng)前提供 this 關(guān)鍵字的綁定的環(huán)境記錄。

在對象調(diào)用了定義了 this 的函數(shù)之前,this 不會被賦值。

由此可得出關(guān)于 this 的完全定義:this 是在程序運行時,通過語言內(nèi)部抽象操作在執(zhí)行上下文中動態(tài)計算得到的,指向調(diào)用使用了其的函數(shù)的對象的變量。

執(zhí)行上下文 vs. This關(guān)鍵字:Execution Context vs. This Keyword

執(zhí)行上下文和 this 關(guān)鍵字的關(guān)系與潛意識相對于意識的關(guān)系類似,執(zhí)行上下文是冰山下深邃龐大而不可窺探的秘地,而 this 只將其一個小部分顯露出來。由于 JavaScript 是面向?qū)ο蟮木幊陶Z言,所以執(zhí)行上下文其實質(zhì)相當(dāng)于一個對象,this 指向了它向開發(fā)者開放了的一系列屬性集合的對象,因而我把 this 叫做執(zhí)行上下文的引用對象。

This因何而來:Why This

JavaScript 在編寫初始借鑒了JAVAC 語言的特性,即便本質(zhì)上不同,但還是把這個如同慣例般存在的 this 拿了過來。使用 this 的原因其實很簡單:

首先,我們時常無法得知調(diào)用了函數(shù)的對象的名稱,并且有時候根本就沒有名稱可以用來引用調(diào)用對象。這是一個迫切的原因,因為我們在開發(fā)時必定會遇到需要引用調(diào)用函數(shù)的對象的場景。

其次,避免重復(fù)指代,就像我們經(jīng)常使用第三人稱來指代前文的主體一樣,作為程序員大家當(dāng)然很樂意使用一個快捷方式來避免機械重復(fù)一些不必要的代碼,這也是“語言”這一重要產(chǎn)品的特性。

最后,它提供給我們實現(xiàn)高級功能的可能性,我們可以通過 this 動態(tài)對于執(zhí)行上下文的指代而實現(xiàn)程序的復(fù)用性和擴展。

This的判斷規(guī)則:Rules of This

this 的根源進(jìn)行深入探究的目的就是為了在開發(fā)中對自己所使用的 this 關(guān)鍵字指代的對象進(jìn)行準(zhǔn)確的判定,它就是一個變量,所以當(dāng)我們使用它的時候,必須清晰地知道它的值到底是什么。

一般來說,我們可以通過確定是哪個對象擁有所調(diào)用的函數(shù)來確定其 this 的指向。這是由于 this 的綁定值是在函數(shù)調(diào)用的時候才賦予的,要看函數(shù)在哪個上下文對象中調(diào)用,但有時候這不是僅用肉眼就能觀察出來的。

此外還要嚴(yán)肅聲明一下,雖然在之前下定義的時候?qū)?this 的概念明確地劃分到了運行階段,但由于它作為一個變量的特性,是可以改變引用值的,它的值的計算與詞法規(guī)則還是息息相關(guān),得將編譯和運行時兩個階段結(jié)合起來,總結(jié)出關(guān)于判斷 this 綁定值的基本原則。

this 關(guān)鍵字綁定的操作是在語言內(nèi)核機制的運行時里執(zhí)行的,由于無法去探索其內(nèi)部,只能通過官方文檔中給出的一系列描述程序來得知其如何判斷,可以梳理出函數(shù)調(diào)用的內(nèi)部過程中對 this 的綁定計算的依據(jù):

前置知識 1: 內(nèi)部機制創(chuàng)建執(zhí)行上下文、初始化函數(shù)所屬領(lǐng)域和創(chuàng)建相關(guān)環(huán)境記錄

在函數(shù)被真正執(zhí)行之前,內(nèi)部機制會執(zhí)行創(chuàng)建擁有函數(shù)的領(lǐng)域、創(chuàng)建執(zhí)行上下文、移交當(dāng)前執(zhí)行上下文控制權(quán)、創(chuàng)建環(huán)境記錄、環(huán)境記錄對象參數(shù)的綁定等一系列操作,為程序運行做編譯準(zhǔn)備。在將函數(shù)推入執(zhí)行棧頂層的時候,對其上下文的歸屬有以下的判斷過程,此處與一個新的概念領(lǐng)域有關(guān):

如果領(lǐng)域中的屬性 this 返回了一個對象,就將內(nèi)部屬性 thisValue 設(shè)置為以此對象為基礎(chǔ)按照規(guī)格創(chuàng)建的 js 對象,否則 thisValue 綁定值為 undefined,表明領(lǐng)域的全局對象(本地全局對象)將設(shè)置為全局對象(程序全局對象)。

這里在新規(guī)范里出現(xiàn)的一個概念領(lǐng)域取代了之前版本中簡單的作用域的概念,由于實現(xiàn)了模塊化等其他新特性,所以作用域的概念可以相當(dāng)于擴展成了現(xiàn)在的領(lǐng)域,它下屬了其他幾個環(huán)境記錄,其中變量的綁定分別在不同環(huán)境記錄中,這里就不做深入解釋了。

領(lǐng)域中比較重要的屬性是領(lǐng)域中的全局對象,這與程序運行時的全局對象的概念要加以區(qū)別,所以可以把領(lǐng)域中的全局對象看作是本地全局變量,其實也就是函數(shù)所屬的上下文對象,它的值就是在剛才的以上的判斷中確定的,如果沒有這個前置對象,就會把全局對象設(shè)置為本地全局對象的值。

前置知識 2: 內(nèi)部機制創(chuàng)建函數(shù)

內(nèi)部機制在詞法分析階段會通過函數(shù)的定義方式向創(chuàng)建函數(shù)操作傳入幾種不同類型的函數(shù)類型:NormalArrowMethod,相對應(yīng)的是普通函數(shù)、箭頭函數(shù)、作為對象方法的函數(shù)。同時在這一步還傳入指定代碼嚴(yán)格模式的參數(shù) strict。然后進(jìn)行函數(shù)的初始化的。

方式 1: 內(nèi)部機制初始化普通函數(shù)

內(nèi)部機制在這一步會設(shè)置函數(shù)的一個重要屬性 ThisMode 的值,它是決定 this 綁定值的依據(jù),它的值是根據(jù)上一步傳入的參數(shù)來判斷的,依次執(zhí)行一下三條判斷分支:

函數(shù)類型為 Arrow:將 ThisMode 賦值為 lexical ,這個值在計算 this 綁定時將按照詞法作用域的規(guī)則來賦值,也就是說 this 的值與定義函數(shù)的詞法作用域中的 this 相一致。

代碼模式為 strict :將 ThisMode 賦值 strict,按照這個值計算 this 綁定時只會將顯式傳入的上下文對象綁定給 this

非以上兩種條件:將 ThisMode 賦值 global,被設(shè)置為 global 之后,函數(shù)在運行階段被調(diào)用時,this 的值就會指向全局對象。

方式 2: 內(nèi)部機制創(chuàng)建對象方法函數(shù)

作為對象屬性的方法是另外來計算 this 的,只有在作為對象方法被調(diào)用的函數(shù),在內(nèi)部創(chuàng)建函數(shù)時才會傳入 Method 值。毫無疑問它將 this 指向了這個前置的對象。構(gòu)造函數(shù)也是同理。

總結(jié)一下對一般使用到的函數(shù)的判斷規(guī)則如下:

箭頭函數(shù):無論調(diào)用位置,取它詞法定義處的外層上下文中綁定的 this,沒有中間本地對象存在時總是能夠取到全局對象。

嚴(yán)格模式:無論調(diào)用位置,只取顯式給定的上下文綁定的 this,通過 call()apply()bind() 方法傳入的第一參數(shù),否則是 undefined

new 關(guān)鍵字調(diào)用的構(gòu)造器函數(shù):無論調(diào)用位置,this 必為在內(nèi)部創(chuàng)建的新的實例對象

顯式綁定上下文對象的普通函數(shù):無論調(diào)用位置,this 必為傳入的上下文對象

方法函數(shù):屬于隱式綁定,無論詞法定義位置,實際情況視調(diào)用處而定:

直接調(diào)用時:this 為前置上下文對象

作為被引用值時:this 為調(diào)用時的上下文對象,在其他對象中引用 this 就是這個調(diào)用它的對象;被全局變量引用,this 就是全局對象。

普通函數(shù):無論詞法定義位置,視調(diào)用處而定,其實質(zhì)在內(nèi)存都都是被作為引用值調(diào)用的,所以 this 都指向全局對象,嚴(yán)格模式規(guī)則優(yōu)先。

另外關(guān)于事件造成的一些 this 誤解可以參考The this keyword這篇文章。其實并不屬于特殊規(guī)則,是由于各種事件監(jiān)聽定義方式本身造成的。

在實際開發(fā)中可以參考《You Don"t Know JS》里關(guān)于 this 的綁定規(guī)則和優(yōu)先級的章節(jié)Nothing But Rules。在這套基礎(chǔ)通用規(guī)則之外,箭頭函數(shù)利用了另一套方式來判斷 this 的綁定值,這篇文章里也有詳盡的敘述。

參考文獻(xiàn):Reference

The ECMAScript 9.0 Standard

Executable Code and Execution Contexts

The ECMAScript 5.1 Standard

The this Keyword

MDN web docs: this

You Don"t Know JS: this & object prototypes

Chapter 1: this Or That?

Chapter 2: this All Makes Sense Now!

Understanding the "this" keyword in JavaScript

The this keyword

StackOverflow: How does the “this” keyword work?

Scope In JavaScript

Understand JavaScript’s “this” With Clarity, and Master It

JavaScript 的 this 原理

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/103655.html

相關(guān)文章

  • 理解JavaScript核心識點:作用域

    摘要:也毫不例外,但在中作用域的特性與其他高級語言稍有不同,這是很多學(xué)習(xí)者久久難以理清的一個核心知識點。主要使用的是函數(shù)作用域。 關(guān)于作用域:About Scope 作用域是程序設(shè)計里的基礎(chǔ)特性,是作用域使得程序運行時可以使用變量存儲值、記錄和改變程序的狀態(tài)。JavaScript 也毫不例外,但在 JavaScript 中作用域的特性與其他高級語言稍有不同,這是很多學(xué)習(xí)者久久難以理清的一個核...

    HelKyle 評論0 收藏0
  • 理解javascript核心識點

    摘要:作用域鏈的作用就是做標(biāo)示符解析。事件循環(huán)還有個明顯的特點單線程。早期都是用作開發(fā),單線程可以比較好當(dāng)規(guī)避同步問題,降低了開發(fā)門檻。單線程需要解決的是效率問題,里的解決思想是異步非阻塞。 0、前言 本人在大學(xué)時非常癡迷java,認(rèn)為java就是世界上最好的語言,偶爾在項目中會用到一些javascript,但基本沒放在眼里。較全面的接觸javascript是在實習(xí)的時候,通過這次的了解發(fā)現(xiàn)...

    laznrbfe 評論0 收藏0
  • 33 個 js 核心概念(三):值類型與引用類型

    摘要:它們的區(qū)別之一就是在計算機中的存儲方式不同基本類型數(shù)據(jù)是將變量名及值存儲在變量對象中,而引用類型的數(shù)據(jù)是將變量名和地址存儲在變量對象中,真正的值是存儲在堆內(nèi)存中。 showImg(https://segmentfault.com/img/remote/1460000017151449); 說點別的 這是《關(guān)于 JavaScript 你必須要知道的 33 個概念 》系列的第三篇文章,今天...

    everfight 評論0 收藏0
  • 十分鐘快速了解《你不知道 JavaScript》(上卷)

    摘要:最近剛剛看完了你不知道的上卷,對有了更進(jìn)一步的了解。你不知道的上卷由兩部分組成,第一部分是作用域和閉包,第二部分是和對象原型。附錄詞法這一章并沒有說明機制,只是介紹了中的箭頭函數(shù)引入的行為詞法。第章混合對象類類理論類的機制類的繼承混入。 最近剛剛看完了《你不知道的 JavaScript》上卷,對 JavaScript 有了更進(jìn)一步的了解。 《你不知道的 JavaScript》上卷由兩部...

    趙春朋 評論0 收藏0
  • JavaScript面向?qū)ο?em>的程序設(shè)計

    摘要:目錄導(dǎo)語理解對象和面向?qū)ο蟮某绦蛟O(shè)計創(chuàng)建對象的方式的繼承機制原型對象原型鏈與原型對象相關(guān)的方法小結(jié)導(dǎo)語前面的系列文章,基本把的核心知識點的基本語法標(biāo)準(zhǔn)庫等章節(jié)講解完本章開始進(jìn)入核心知識點的高級部分面向?qū)ο蟮某绦蛟O(shè)計,這一部分的內(nèi)容將會對對象 目錄 導(dǎo)語 1.理解對象和面向?qū)ο蟮某绦蛟O(shè)計 2.創(chuàng)建對象的方式 3.JavaScript的繼承機制 3.1 原型對象 3.2 原型鏈 3.3 與...

    gitmilk 評論0 收藏0

發(fā)表評論

0條評論

TerryCai

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<