摘要:這一篇簡單的說一說的函數(shù)執(zhí)行和的執(zhí)行上下文的概念,之前在我的博客里邊也提到過的堆棧隊(duì)列,這一篇打算多帶帶的拿出來說一說是什么是的執(zhí)行上下文一段可以執(zhí)行的代碼在被執(zhí)行的時候,會創(chuàng)建一個函數(shù)的執(zhí)行上下文執(zhí)行上下文里邊有三個重要的屬性分別是變量對象
這一篇簡單的說一說js的函數(shù)執(zhí)行和js的執(zhí)行上下文的概念,之前在我的博客里邊也提到過
js的堆棧隊(duì)列,
這一篇打算多帶帶的拿出來說一說
一段可以執(zhí)行的代碼在被執(zhí)行的時候,會創(chuàng)建一個函數(shù)的執(zhí)行上下文
執(zhí)行上下文里邊有三個重要的屬性分別是
變量對象
作用域鏈
this指向
執(zhí)行上下文是跟函數(shù)相關(guān)的,執(zhí)行上下文分為兩個階段
創(chuàng)建階段
執(zhí)行階段
首先創(chuàng)建階段
掃描變量和函數(shù)(確定變量環(huán)境)
確定this指向
確定詞法環(huán)境
簡單說一下詞法環(huán)境和變量環(huán)境的區(qū)別,我個人理解的就是說詞法環(huán)境是包含變量環(huán)境的
在js里邊原型鏈大家都不陌生 ,js在當(dāng)前的對象里邊找不到所使用的屬性的話會去他的上一級去找
直到Object,再找不到就會undefined ,這里邊 當(dāng)前對象的作用域就是他的變量環(huán)境,而詞法環(huán)境則是與之關(guān)聯(lián)的的執(zhí)行上下文中聲明的變量
在創(chuàng)建階段 函數(shù)的聲明會被儲存在當(dāng)前的變量環(huán)境之中,var的變量的話則會被設(shè)置成undefined
,所以我們在聲明之前就可以訪問到var聲明的變量 ,but他是一個undfined
然后就是執(zhí)行階段了
這個時候已經(jīng)完成了對所有變量的分配,開始執(zhí)行代碼
變量對象什么是變量對象,變量對象就是與執(zhí)行上下文相關(guān)得數(shù)據(jù)得一個作用域,這里邊存儲了在這個上下文里邊定義的而變量和函數(shù)聲明
函數(shù)聲明的時候會在創(chuàng)建階段的時候聲明一個函數(shù)指針全局上下文和函數(shù)上下文
故名思與函數(shù)上下文,在函數(shù)被執(zhí)行的時候創(chuàng)建,那么全局上下文是什么時候被創(chuàng)建的呢,首先我們要知道一個概念就是,全局對象
在一般的函數(shù)里邊全局對象可以用this引用其屬性,客戶端的話是window對象
console.log(this);
可以嘗試著去打印一下this,如下圖可以看到,window對象里邊有很多我們常用或者常見的屬性和方法
當(dāng)然也有一些其他的情況this并不是指向的window對象,this指向 這個東西,我們會在下邊說
當(dāng)然js 萬物皆對象不只是說說
用 instanceof 輸出一下this 會發(fā)現(xiàn)也是一個object
console.log(this instanceof Object);
所以說全局對象是一個object的實(shí)例化對象
所以說說白了全局上下文就是在一開始就被創(chuàng)建的,全局上下文是由在瀏覽器關(guān)閉或者刷新的時候才會銷毀, 然后這個window對象其實(shí)就是全局上下文的變量對象
函數(shù)上下文和上邊所說的意思差不多,但是,啊,但是,在函數(shù)上下文中的時候,函數(shù)里邊的變量對象是活動對象,他的英文名字叫做 actiation object ,大面上看的意思就是說只有進(jìn)入了這個執(zhí)行上下文中的時候,也就是說執(zhí)行到了這個函數(shù)的時候,其中的變量對象才會被激活,才會能被訪問,在沒有執(zhí)行到這個函數(shù)的時候,其屬性是不能訪問的,這里是和全局上下文不同的。
函數(shù)執(zhí)行過程function foo(a) { var b = 2; function c() {} var d = function() {}; b = 3; } foo(1);
首先看這段代碼,上邊也說了,函數(shù)執(zhí)行有兩個階段創(chuàng)建階段和執(zhí)行階段
首先進(jìn)如執(zhí)行上下文,進(jìn)入創(chuàng)建階段
首先形參,也就是調(diào)用的方法的時候傳進(jìn)來的值,如果你傳了就是有值得,如果沒傳就是一個undefined,相應(yīng)得函數(shù)里邊會有一個arguments對象,存放著形參得值,
然后函數(shù)里邊聲明得變量,在創(chuàng)建階段得時候是沒有值得,會被賦值一個undefined。
函數(shù)聲明會由名稱和對應(yīng)值組成一個變量對象的屬性被創(chuàng)建,也就是上邊說的函數(shù)得指針,我是這么理解得,因?yàn)檫@個變量指向了這個函數(shù),如果變量對象已經(jīng)存在相同名稱的屬性,則完全替換這個屬性
上邊這段代碼在創(chuàng)建階段是這樣得
{ arguments: { 0: 1, length: 1 }, a: 1, b: undefined, c: reference to function c(){}, d: undefined }
然后函數(shù)的而執(zhí)行階段,這個時候就該干嘛干嘛了,函數(shù)里邊聲明的變量,賦值等等的會在這里根據(jù)代碼,修改變量的值
{ arguments: { 0: 1, length: 1 }, a: 1, b: 3, c: reference to function c(){}, d: reference to FunctionExpression "d" }
得出一個結(jié)論,函數(shù)的執(zhí)行上下文里邊在初始化的時候只包含一個arguments對象,其他的屬性是沒有值的,為了直觀一點(diǎn) ,舉個例子
function foo() { console.log(a); a = 1; } foo(); function bar() { a = 1; console.log(a); } bar();
比如說這個在foo函數(shù)的上下文里邊打印a, 但是foo 里邊沒有用var聲明,下邊的a就找不到所以會打印一個 a is not defined。
但是第二個的話會打印一個1,因?yàn)榇钶d因之前,全局對象里邊已經(jīng)有了a屬性
最后就是,在上文提到
c: reference to function c(){}, d: reference to FunctionExpression "d"
在上下文創(chuàng)建的時候,變量是不會覆蓋這種聲明的,比如說
console.log(foo); function foo(){ console.log("foo"); } var foo = 1;
會打印這個函數(shù),但是, 啊,但是,如果是這樣
function foo(){ console.log("foo"); } var foo = 1; console.log(foo);
這樣的話就變成了剛才所說的賦值了 ,會打印1
以上是我對js函數(shù)的執(zhí)行與上下文的一些認(rèn)識,剛從博客園搬過來,有不足的希望指正
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/105480.html
摘要:思考題在深入學(xué)習(xí)之詞法作用域和動態(tài)作用域中,提出這樣一道思考題思考題一思考題二兩段代碼都會打印但是還是有些許差異的,本文就詳細(xì)的解析執(zhí)行上下文棧和執(zhí)行上下文的具體變化過程。 在《深入學(xué)習(xí)js之——執(zhí)行上下文棧》中說過,當(dāng)JavaScript代碼執(zhí)行一段可執(zhí)行代碼(executable code)時,會創(chuàng)建對應(yīng)的執(zhí)行上下文(execution context) 對于每一個執(zhí)行上下文,都有...
摘要:圖片轉(zhuǎn)引自的演講和兩個定時器中回調(diào)的執(zhí)行邏輯便是典型的機(jī)制。異步編程關(guān)于異步編程我的理解是,在執(zhí)行環(huán)境所提供的異步機(jī)制之上,在應(yīng)用編碼層面上實(shí)現(xiàn)整體流程控制的異步風(fēng)格。 問題背景 在一次開發(fā)任務(wù)中,需要實(shí)現(xiàn)如下一個餅狀圖動畫,基于canvas進(jìn)行繪圖,但由于對于JS運(yùn)行環(huán)境中異步機(jī)制的不了解,所以遇到了一個棘手的問題,始終無法解決,之后在與同事交流之后才恍然大悟。問題的根節(jié)在于經(jīng)典的J...
摘要:深入之繼承的多種方式和優(yōu)缺點(diǎn)深入系列第十五篇,講解各種繼承方式和優(yōu)缺點(diǎn)。對于解釋型語言例如來說,通過詞法分析語法分析語法樹,就可以開始解釋執(zhí)行了。 JavaScript深入之繼承的多種方式和優(yōu)缺點(diǎn) JavaScript深入系列第十五篇,講解JavaScript各種繼承方式和優(yōu)缺點(diǎn)。 寫在前面 本文講解JavaScript各種繼承方式和優(yōu)缺點(diǎn)。 但是注意: 這篇文章更像是筆記,哎,再讓我...
摘要:執(zhí)行上下文和執(zhí)行棧是中關(guān)鍵概念之一,是難點(diǎn)之一。理解執(zhí)行上下文和執(zhí)行棧同樣有助于理解其他的概念如提升機(jī)制作用域和閉包等。函數(shù)執(zhí)行完成,函數(shù)的執(zhí)行上下文出棧,并且被銷毀。 前言 如果你是一名 JavaScript 開發(fā)者,或者想要成為一名 JavaScript 開發(fā)者,那么你必須知道 JavaScript 程序內(nèi)部的執(zhí)行機(jī)制。執(zhí)行上下文和執(zhí)行棧是JavaScript中關(guān)鍵概念之一,是Ja...
摘要:執(zhí)行上下文和執(zhí)行棧是中關(guān)鍵概念之一,是難點(diǎn)之一。理解執(zhí)行上下文和執(zhí)行棧同樣有助于理解其他的概念如提升機(jī)制作用域和閉包等。函數(shù)執(zhí)行完成,函數(shù)的執(zhí)行上下文出棧,并且被銷毀。 前言 如果你是一名 JavaScript 開發(fā)者,或者想要成為一名 JavaScript 開發(fā)者,那么你必須知道 JavaScript 程序內(nèi)部的執(zhí)行機(jī)制。執(zhí)行上下文和執(zhí)行棧是JavaScript中關(guān)鍵概念之一,是Ja...
閱讀 2240·2021-09-07 09:58
閱讀 3421·2019-08-30 14:07
閱讀 1328·2019-08-29 12:32
閱讀 694·2019-08-29 11:06
閱讀 3720·2019-08-26 18:18
閱讀 3760·2019-08-26 17:35
閱讀 1403·2019-08-26 11:35
閱讀 637·2019-08-26 11:35