日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Javascript执行上下文和执行栈

發布時間:2023/12/1 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Javascript执行上下文和执行栈 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  什么是執行上下文?

  執行上下文就是當前JavaScript代碼被解析和執行時所在環境的抽象概念,JavaScript中運行任何的代碼都是在執行上下文。

  什么是執行棧?

  執行棧,在其他編程語言中也被叫做調用棧,具有LIFO(后進先出)結構,用于存儲在代碼執行期間創建的所有執行上下文。當JavaScript引擎首次讀取腳本時,它會創建一個全局執行上下文并將其推入當前的執行棧。每當發生一個函數調用,引擎都會為該函數創建一個新的執行上下文,并將其推到當前執行棧的頂端。引擎會運行執行上下文在執行棧頂端的函數,當此函數運行完成后,其對應的執行上下文將會從執行棧中彈出,上下文控制權將移到當前執行棧的下一個執行上下文。所以程序結束以前,執行棧最底部永遠有一個globalContext。

  執行上下文的類型

  執行上下文總共有三種類型:

  一、全局執行上下文:這是默認的,基礎的執行上下文。不在任何函數中的代碼都位于全局執行上下文中,做了兩件事:1.創建一個全局對象,在瀏覽器中這個全局對象就是window對象。2.將this指針指向這個全局對象。一個程序中只能存在一個全局執行上下文。

  二、函數執行上下文:每次調用函數時,都會為該函數創建一個新的執行上下文。每個函數都擁有自己的執行上下文,但是只有在函數被調用的時候才會被創建。一個程序中可以存在任意數量的函數執行上下文。每當一個新的執行上下文被創建,它都會按照特定的順序執行一系列步驟。

  三、Eval函數執行上下文:運行在eval函數中的代碼也獲得自己的執行上下文,不常用函數,不建議使用。

  執行上下文如何被創建?

  執行上下文分兩個階段創建:1)創建階段;2)執行階段

  一、創建階段:在任意的JavaScript代碼被執行之前,執行上下文處于創建階段。在創建階段中總共發生了三件事情:

    1.確定this的值,也被稱為This Binding;

    2.LexicalEnvironment(詞法環境)組件被創建。

    3.VariableEnvironment(變量環境)組件被創建。

創建階段

    Ⅰ、This Binding:

      在全局執行上下文中,this的值指向全局對象,在瀏覽器中,this的值指向window對象。在函數指向上下文中,this的值取決于函數的調用方式。如果它被一個對象引用調用,那么this的值被設置為該對象,否則this的值被設置為全局對象或undefined(嚴格模式下)。

    Ⅱ、LexicalEnvironment(詞法環境):

      ES6文檔將詞法環境定義為:詞法環境是一種規范類型,基于ECMAScript代碼的詞法嵌套結構來定義標識符與特定變量和函數的關聯關系(environment record)和可能為空引用(null)的外部詞法環境組成。簡而言之,詞法環境是一個包含標識符變量映射的結構。(這里的標識符表示變量/函數的名稱,變量是對實際對象【包含函數類型對象】或原始值的引用)

     在LexicalEnvironment(詞法環境)中,有兩個部分組成:(1)環境記錄(environment record):是存儲變量和函數聲明的實際位置 (2)對外部環境的引用:意味著它可以訪問外部詞法環境。

      LexicalEnvironment(詞法環境)有兩種類型:

        1.全局環境(在全局執行上下文中)是一個沒有外部環境的詞法環境。全局環境的外部環境引用為null。它擁有一個全局對象(window對象)及其關聯的方法和屬性(例如數組方法)以及任何用戶自定義的全局變量,this的值指向這個全局對象。

        2.函數環境,用戶在函數中定義的變量被存儲在環境記錄中,對外部環境的引用可以是全局,也可以是包含內部函數的外部函數環境。

        注意:對于函數環境而言,環境記錄還包含了一個arguments對象,該對象包含了索引和傳遞給函數的參數之間的映射以及傳遞給函數的長度(數量)。

      環境記錄同樣有兩種類型:

        1.聲明性環境記錄:存儲變量、函數和參數。一個函數環境包含聲明性環境記錄。

        2.對象環境記錄:用于定義在全局執行上下文中出現的變量和函數的關聯。全局環境包含對象環境記錄。

    Ⅲ、VariableEnvironmen(變量環境):

      它也是一個詞法環境,其EnvironmentRecord包含了由VariableStatements在此執行上下文創建的綁定。它具有上面定義的語法環境的所有屬性。與LexicalEnvironment的區別在于前者用于存儲函數聲明和變量(let和const)綁定,而后者僅用于存儲變量(var)綁定。

    結合實例分析:

let a=10;const b=20;var c;function addFun (e,f){var g =50;return e*f*g;}c = addFun(30,40)/*GlobalExecutionContext = {ThisBinding = <Global Object> //確定thisLexicalEnvironment = {EnvironmentRecord:{Type:'Object' //全局環境//標識符綁定a:<uninitialized>,b:<uninitialized>,addFun:<Func>},outer:<null> //對外部環境的引用}, //詞法環境VariableEnvironment = {EnvironmentRecord:{Type:'Object' //全局環境//標識符綁定c:undefined},outer:<null> //對外部環境的引用} //變量環境}FunctionExecutionContext = {ThisBinding = <Global Object> //確定thisLexicalEnvironment = {EnvironmentRecord:{Type:'Declarative' //函數環境//標識符綁定Arguments:{0:30,1:40,length:2}},outer:<GlobalLexicalEnvironment>//對外部環境的引用}, //詞法環境VariableEnvironment = {EnvironmentRecord:{Type:'Declarative' //函數環境//標識符綁定g:undefined},outer:<GlobalLexicalEnvironment>//對外部環境的引用} //變量環境}*/

  只有在addFun調用的時候才會創建函數執行上下文。創建之初,代碼會被掃描并解析變量和函數聲明,其中函數聲明存儲在環境之中,而變量會被設置為undefined(在var情況下)或保持未初始化(在let和const情況下)。這也是為什么可以在聲明之前訪問var定義的變量(盡管是undefined),但如果在let或const之前訪問定義的變量會提示引用錯誤的原因。

  這就是所謂的變量提升。

  函數上下文

  在函數上下文中,用活動對象(activation object,AO)來表示變量對象。

  活動對象和變量對象的區別在于:

    1.變量對象(VO)是規范上或者是JS引擎上實現的,并不能在JS環境中直接訪問。

    2.當進入到一個執行上下文后,這個變量才會被激活,所以叫活動變量(AO),這個時候活動變量上的各種屬性才能被訪問。

  調用函數的時候,會為其創建一個Arguments對象,并自動初始化局部變量arguments,指代該Arguments對象。所有作為參數傳入的值都會成為Arguments對象的數組元素。

  二、執行階段分為兩個階段。注:在執行階段,如果JavaScript引擎在源代碼中聲明的位置找不到let變量的值,那么將為其分配undefined的值。

    Ⅰ、進入執行階段

      此時的變量對象會進行初始化:

        1.函數的所有形參:沒有實參,屬性值設為undefined。

        2.函數聲明:如果變量對象已經存在相同的屬性,則完全替換這個屬性。

        3.變量聲明:如果變量名稱跟已經聲明的形參或函數相同,則變量聲明不會干擾已經存在的屬性。

    Ⅱ、代碼執行

      這個階段會順序執行代碼,修改變量對象的值。

  執行階段總結:

    1.全局上下文的變量初始化是全局對象;

    2.函數上下文的變量對象初始化只包括Arguments對象;

    3.在進入執行上下文時會給變量對象添加形參,函數聲明,變量聲明等初始屬性值

    4.在代碼執行階段,會再次修改變量對象的屬性值。

轉載于:https://www.cnblogs.com/xuxiaoqiangAndHM/p/10514247.html

總結

以上是生活随笔為你收集整理的Javascript执行上下文和执行栈的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。