摘要:思考題在深入學習之詞法作用域和動態(tài)作用域中,提出這樣一道思考題思考題一思考題二兩段代碼都會打印但是還是有些許差異的,本文就詳細的解析執(zhí)行上下文棧和執(zhí)行上下文的具體變化過程。
在《深入學習js之——執(zhí)行上下文?!分姓f過,當JavaScript代碼執(zhí)行一段可執(zhí)行代碼(executable code)時,會創(chuàng)建對應的執(zhí)行上下文(execution context)
對于每一個執(zhí)行上下文,都有三個重要的屬性:
變量對象(Variable object VO)
作用域鏈(Scope chain)
this
本文我們結(jié)合著這三個部分的內(nèi)容,講講執(zhí)行上下文的具體處理過程。
思考題在《深入學習js之——詞法作用域和動態(tài)作用域》中,提出這樣一道思考題:
// 思考題一: var scope = "global scope"; function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f(); } checkscope(); // 思考題二: var scope = "global scope"; function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f; } checkscope()();
兩段代碼都會打印local scope,但是還是有些許差異的,本文就詳細的解析執(zhí)行上下文棧和執(zhí)行上下文的具體變化過程。
具體分析我們分析第一段代碼:
var scope = "global scope"; function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f(); } checkscope();
執(zhí)行過程如下:
1、執(zhí)行全局代碼,創(chuàng)建全局執(zhí)行上下文,全局上下文被壓入執(zhí)行上下文棧
ECStack = [ globalContext ];
2、全局上下文初始化
globalContext = { VO: [global], Scope: [globalContext.VO], this: globalContext.VO }
2、初始化的同時,checkscope 函數(shù)被創(chuàng)建,保存作用域鏈到函數(shù)內(nèi)部的屬性[[scope]]
checkscope.[[scope]] = [ globalContext.VO ];
3、執(zhí)行checkScope 函數(shù),創(chuàng)建checkScope 函數(shù)執(zhí)行上下文,checkScope 函數(shù)執(zhí)行上下文被壓入執(zhí)行上下文棧:
ECStack = [ checkscopeContext, globalContext ];
4、checkscope 函數(shù)執(zhí)行上下文初始化:
1.復制函數(shù) [[scope]] 屬性創(chuàng)建作用域鏈,
2.用 arguments 創(chuàng)建活動對象,
3.初始化活動對象,即加入形參、函數(shù)聲明、變量聲明,
4.將活動對象壓入 checkscope 作用域鏈頂端,
同時 f 函數(shù)被創(chuàng)建,保存作用域鏈到 f 函數(shù)的內(nèi)部屬性[[scope]]
checkscopeContext = { AO: { arguments: { length: 0 }, scope: undefined, f: reference to function f(){} }, Scope: [AO, globalContext.VO], this: undefined }
5、執(zhí)行f函數(shù),創(chuàng)建 f 函數(shù)執(zhí)行上下文,f 函數(shù)執(zhí)行上下文被壓入執(zhí)行上下文棧
ECStack = [ fContext, checkscopeContext, globalContext ]
6、f 函數(shù)執(zhí)行上下文初始化, 以下跟第 4 步相同:
1.復制函數(shù) [[scope]] 屬性創(chuàng)建作用域鏈
2.用 arguments 創(chuàng)建活動對象
3.初始化活動對象,即加入形參、函數(shù)聲明、變量聲明
4.將活動對象壓入 f 作用域鏈頂端
fContext = { AO: { arguments: { length: 0 } }, Scope: [AO, checkscopeContext.AO, globalContext.VO], this: undefined }
7、f 函數(shù)執(zhí)行,沿著作用域鏈查找 scope 值,返回 scope 值
8、f 函數(shù)執(zhí)行完畢,f 函數(shù)上下文從執(zhí)行上下文棧中彈出
ECStack = [ checkscopeContext, globalContext ]
9、checkscope 函數(shù)執(zhí)行完畢,checkscope 執(zhí)行上下文從執(zhí)行上下文棧中彈出
ECStack = [ globalContext ]
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/102558.html
摘要:開篇作用域是每種計算機語言最重要的基礎(chǔ)之一,因此要想深入的學習作用域和作用域鏈就是個繞不開的話題。這樣由多個執(zhí)行上下文的變量對象構(gòu)成的鏈表就叫做作用域鏈。這時候執(zhí)行上下文的作用域鏈,我們命名為至此,作用域鏈創(chuàng)建完畢。 開篇 作用域是每種計算機語言最重要的基礎(chǔ)之一,因此要想深入的學習JavaScript,作用域和作用域鏈就是個繞不開的話題。 在《深入學習js之—-執(zhí)行上下文?!分形覀兲岬?..
摘要:當遇到函數(shù)調(diào)用時,引擎為該函數(shù)創(chuàng)建一個新的執(zhí)行上下文并把它壓入當前執(zhí)行棧的頂部。參考鏈接理解中的執(zhí)行上下文和執(zhí)行棧深入之執(zhí)行上下文棧 開篇 作為一個JavaScript的程序開發(fā)者,如果被問到JavaScript代碼的執(zhí)行順序,你腦海中是不是有一個直觀的印象 -- JavaScript 是順序執(zhí)行的,可事實真的是這樣的嗎? 讓我們首先看兩個小例子: var foo = functio...
摘要:寫在前面深入系列共計篇已經(jīng)正式完結(jié),這是一個旨在幫助大家,其實也是幫助自己捋順底層知識的系列。深入系列自月日發(fā)布第一篇文章,到月日發(fā)布最后一篇,感謝各位朋友的收藏點贊,鼓勵指正。 寫在前面 JavaScript 深入系列共計 15 篇已經(jīng)正式完結(jié),這是一個旨在幫助大家,其實也是幫助自己捋順 JavaScript 底層知識的系列。重點講解了如原型、作用域、執(zhí)行上下文、變量對象、this、...
摘要:在中的應用采用詞法作用域,也就是靜態(tài)作用域。那什么又是詞法作用域或者靜態(tài)作用域呢請繼續(xù)往下看靜態(tài)作用域與動態(tài)作用域因為采用的是詞法作用域函數(shù)的作用域在函數(shù)定義的時候就決定了。 開篇 當我們在開始學習任何一門語言的時候,都會接觸到變量的概念,變量的出現(xiàn)其實是為了解決一個問題,為的是存儲某些值,進而,存儲某些值的目的是為了在之后對這個值進行訪問或者修改,正是這種存儲和訪問變量的能力將狀態(tài)給...
摘要:模塊化是隨著前端技術(shù)的發(fā)展,前端代碼爆炸式增長后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調(diào)也不等同于異步。將會討論安全的類型檢測惰性載入函數(shù)凍結(jié)對象定時器等話題。 Vue.js 前后端同構(gòu)方案之準備篇——代碼優(yōu)化 目前 Vue.js 的火爆不亞于當初的 React,本人對寫代碼有潔癖,代碼也是藝術(shù)。此篇是準備篇,工欲善其事,必先利其器。我們先在代...
閱讀 3422·2023-04-26 01:46
閱讀 2962·2023-04-25 20:55
閱讀 5545·2021-09-22 14:57
閱讀 3004·2021-08-27 16:23
閱讀 1742·2019-08-30 14:02
閱讀 2096·2019-08-26 13:44
閱讀 673·2019-08-26 12:08
閱讀 3003·2019-08-26 11:47