成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

JavaScript 如何執(zhí)行上下文

開(kāi)發(fā) 前端
今天這篇文章,我們將了解 JavaScript 提供的黑盒,讓我們的代碼神奇地運(yùn)行“執(zhí)行上下文”。

這是迄今為止最重要的主題之一,它可以使你對(duì)其他關(guān)鍵主題一目了然,例如,作用域、詞法作用域、閉包和提升,而且學(xué)習(xí)JavaScript的真正工作原理很有趣。

到目前為止,在代碼編輯器(Vs code )中編寫(xiě)的每一行混亂代碼都在我們現(xiàn)在將討論的這個(gè)執(zhí)行上下文中運(yùn)行。

坐下來(lái),放松一下,收拾好你的美食,因?yàn)槲視?huì)讓你明白的。

在 JavaScript 中,一切都發(fā)生在執(zhí)行上下文中,我的意思是一切。你可以將其視為評(píng)估和執(zhí)行 JavaScript 代碼的環(huán)境。

每當(dāng)你的瀏覽器與任何 JavaScript 代碼交叉路徑時(shí),瀏覽器的 JavaScript 引擎就會(huì)創(chuàng)建一個(gè)特殊的環(huán)境來(lái)處理此 JavaScript 代碼的轉(zhuǎn)換和執(zhí)行。這個(gè)環(huán)境被稱為執(zhí)行上下文。

執(zhí)行上下文包含當(dāng)前正在運(yùn)行的代碼以及有助于其執(zhí)行的所有內(nèi)容。

執(zhí)行上下文的類型

當(dāng)你在瀏覽器中運(yùn)行腳本時(shí),javascript 引擎會(huì)創(chuàng)建不同類型的執(zhí)行上下文。

全局執(zhí)行上下文 (GEC)

當(dāng)你第一次運(yùn)行腳本或你的代碼不在任何函數(shù)中時(shí),它會(huì)被放置在全局執(zhí)行上下文 (GEC) 中。

在這里,每當(dāng) JavaScript 引擎接收到一個(gè)腳本文件時(shí),它首先會(huì)創(chuàng)建一個(gè)默認(rèn)執(zhí)行上下文,這就是我們所說(shuō)的全局執(zhí)行上下文 (GEC)。它是一個(gè)基本/默認(rèn)執(zhí)行上下文,所有不在函數(shù)內(nèi)部的代碼都會(huì)在其中執(zhí)行。

注意:每個(gè) JavaScript文件只有一個(gè) GEC

函數(shù)執(zhí)行上下文 (FEC)

每當(dāng)你的 JavaScript 引擎遇到函數(shù)調(diào)用時(shí),它都會(huì)在全局執(zhí)行上下文中創(chuàng)建一種稱為函數(shù)執(zhí)行上下文的不同類型的 EC,以評(píng)估和執(zhí)行該函數(shù)內(nèi)部編寫(xiě)的代碼。

每個(gè)函數(shù)調(diào)用都有自己的 FEC(即使你多次調(diào)用同一個(gè)函數(shù)),因此,在腳本運(yùn)行時(shí)可以有多個(gè) FEC。

它們是如何創(chuàng)建的?

現(xiàn)在執(zhí)行上下文的創(chuàng)建分兩個(gè)階段進(jìn)行:

  •  創(chuàng)建階段
  •  執(zhí)行階段

1、創(chuàng)建階段

在此階段,將創(chuàng)建一個(gè)執(zhí)行上下文對(duì)象 (ECO),其中包含我們的代碼在其運(yùn)行時(shí)(執(zhí)行階段)使用的重要信息/數(shù)據(jù)。

屬性在此對(duì)象 (ECO) 中分三個(gè)不同階段進(jìn)行設(shè)置和定義。

   創(chuàng)建變量對(duì)象 (VO)。

   創(chuàng)建范圍鏈。

   賦予此關(guān)鍵字價(jià)值。

階段 1:變量對(duì)象的創(chuàng)建

變量對(duì)象就像一個(gè)在執(zhí)行上下文中創(chuàng)建的容器,它將變量和函數(shù)聲明存儲(chǔ)在鍵:值對(duì)(不是函數(shù)表達(dá)式)中。

在 GEC 中,使用 var 關(guān)鍵字聲明的每個(gè)變量都會(huì)向指向該變量的變量對(duì)象添加一個(gè)屬性,并將其值設(shè)置為未定義,使用 let 或 const 聲明的變量獲取未初始化的值,而在函數(shù)聲明中,一個(gè)屬性被添加到指向該函數(shù)的變量對(duì)象中,所有的函數(shù)聲明都將被存儲(chǔ)并可以在 VO 中訪問(wèn),甚至在代碼開(kāi)始運(yùn)行之前。

在 FEC 中,不會(huì)創(chuàng)建此變量對(duì)象,而是構(gòu)造了一個(gè)名為“argument”的類似數(shù)組的對(duì)象,其中包括提供給該函數(shù)的所有參數(shù)。

這種甚至在代碼執(zhí)行之前就將變量和函數(shù)(聲明)存儲(chǔ)在內(nèi)存中,這就是我們所說(shuō)的提升。

第 2 階段:創(chuàng)建范圍鏈

在 JavaScript 中,作用域是一種了解一段代碼對(duì)腳本其他域的可訪問(wèn)性的方法。

每個(gè)函數(shù)執(zhí)行上下文都會(huì)創(chuàng)建它的作用域,可以將其視為一個(gè)環(huán)境或空間,它定義的變量和函數(shù)可以通過(guò)一個(gè)稱為作用域的進(jìn)程來(lái)訪問(wèn)。

現(xiàn)在,當(dāng)一個(gè)函數(shù)(比如 X() )在另一個(gè)函數(shù)(比如 Y() )中定義時(shí),這個(gè)內(nèi)部函數(shù) X() 將可以訪問(wèn)變量,并且在外部函數(shù) Y() 中定義的其他函數(shù)也將具有訪問(wèn)外部函數(shù)的代碼,但事情并不止于此,它還可以訪問(wèn)其父元素的代碼等等,直到 GCE,這種行為就是我們所說(shuō)的詞法作用域,但反過(guò)來(lái)不是真的。

這個(gè)作用域的概念在JavaScript 中引發(fā)了一個(gè)被稱為閉包的相關(guān)現(xiàn)象,即使在外部函數(shù)執(zhí)行完成之后,內(nèi)部函數(shù)也可以訪問(wèn)與外部函數(shù)關(guān)聯(lián)的代碼……它已經(jīng)死了,消失了,很久了走了。

讓我們?cè)倏匆粋€(gè)例子來(lái)理解作用域鏈。

let a = 10;
function first() {
let b = 20;
second();
function second() {
let c = 30;
console.log(a + b + c);
}
}
first(); // output is 60

這里變量 a 和 b 沒(méi)有在函數(shù) second() 中定義,它只能訪問(wèn)在其自己的范圍(本地范圍)中定義的變量 c,但是由于詞法范圍,它可以訪問(wèn)它所在的函數(shù)以及它的父母。因此,當(dāng)你運(yùn)行此代碼時(shí),JavaScript 引擎將無(wú)法找到變量 a 或 b,因此,它將沿著執(zhí)行上下文鏈?zhǔn)紫日业?b 并解析它,因?yàn)樗言诤瘮?shù) first() 范圍內(nèi)成功找到它,解析后繼續(xù)查找變量 a ,JavaScript 引擎為該變量一直到全局執(zhí)行上下文并解析它。

這個(gè) JavaScript 引擎沿著不同執(zhí)行上下文鏈向上的過(guò)程,或者我們可以說(shuō)遍歷執(zhí)行上下文的范圍以解析變量或函數(shù)調(diào)用/調(diào)用,稱為 Scope Chaining。

第 3 階段:設(shè)置“this”關(guān)鍵字的值

在 javascript 中,this 關(guān)鍵字是指執(zhí)行上下文所屬的范圍。

在 GEC 中,這指的是一個(gè)全局對(duì)象,在瀏覽器的情況下是一個(gè)窗口對(duì)象。因此,在函數(shù)聲明中,使用“var”關(guān)鍵字初始化的變量分別作為方法和屬性分配給這個(gè)全局對(duì)象。

所以

var x = "hello"            
function y() {
console.log("hello")
}

與以下內(nèi)容相同

window.x = "hello"            
window.y = () => {
console.log("hello")
}

但在 FEC 的情況下,它不會(huì)創(chuàng)建“this”關(guān)鍵字,而是可以訪問(wèn)定義它的環(huán)境的關(guān)鍵字。

執(zhí)行階段

在執(zhí)行上下文的這個(gè)階段,我們的代碼開(kāi)始執(zhí)行,執(zhí)行后從執(zhí)行堆棧或調(diào)用堆棧彈出,我們將在本文后面介紹。

到目前為止,Variable 對(duì)象包含值為 undefined 和 uninitialized 的變量,具體取決于變量是分別使用 var 關(guān)鍵字還是使用 let/const 聲明的。

這里 JavaScript引擎再次讀取 EC 中的代碼,用它們的實(shí)際值更新這些變量。然后代碼被解析,被轉(zhuǎn)譯,最后被執(zhí)行

執(zhí)行堆棧(調(diào)用堆棧)

你有沒(méi)有想過(guò) JavaScript 引擎如何跟蹤它在腳本運(yùn)行時(shí)創(chuàng)建的各種 EC 的所有這些創(chuàng)建和刪除?答案是執(zhí)行堆棧或簡(jiǎn)單的調(diào)用堆棧。

“JavaScript 是一種同步的單線程語(yǔ)言”

單線程是指它只能夠一次執(zhí)行一個(gè)任務(wù),一次是一行代碼,而同步是指這些任務(wù)的執(zhí)行以特定的順序發(fā)生。因此,當(dāng) JavaScript 引擎讀取腳本時(shí),它會(huì)創(chuàng)建不同的執(zhí)行上下文并將它們存儲(chǔ)在稱為調(diào)用堆棧或執(zhí)行堆棧的堆棧數(shù)據(jù)結(jié)構(gòu)中。

var name = "Victor";
function firstFunc() {
var a = "Hi!";
secondFunc();
console.log(`${a} ${name}`);
}
function secondFunc(){
var b = "Hey!";
third();
console.log(`${b} ${name}`);
}
function thirdFunc() {
var c = "Hello!";
console.log(`${c} ${name}`);
}
first();

當(dāng)腳本在瀏覽器中加載時(shí),瀏覽器的 JS 引擎首先會(huì)創(chuàng)建一個(gè)我們?cè)谏厦嬖敿?xì)介紹過(guò)的默認(rèn)特殊環(huán)境,即全局執(zhí)行上下文,并將其推送到此執(zhí)行堆棧。

之后,當(dāng) JS 引擎發(fā)現(xiàn)函數(shù)調(diào)用時(shí)執(zhí)行文件時(shí),它會(huì)為其創(chuàng)建一個(gè)單獨(dú)的函數(shù)執(zhí)行上下文,如下圖所示(步驟 2),并將其推送到現(xiàn)有默認(rèn) GEC 之上的堆棧中。

在執(zhí)行 firstFunc() 時(shí),它遇到對(duì) secondFunc() 的調(diào)用,它暫停 firstFunc() 的執(zhí)行并創(chuàng)建另一個(gè) FEC 并推送到 firstFunc() FEC 頂部的堆棧,然后再次為 thirdFunc() 創(chuàng)建一個(gè)單獨(dú)的 FEC 稱呼。

頂部的 EC 將首先由 JS 引擎執(zhí)行,執(zhí)行完成后,它會(huì)從堆棧中彈出,并開(kāi)始執(zhí)行上一個(gè)活動(dòng) EC 下面的 EC,如上圖所示,直到到達(dá) GEC。

結(jié)論

執(zhí)行上下文是 JavaScript 的核心,理解它很重要,因?yàn)樗梢詭椭阏_理解其他主要概念。

希望這篇文章對(duì)你有所幫助,如果你覺(jué)得有用的話,請(qǐng)將它分享給你的朋友,最后,感謝你的閱讀,祝編程愉快!

責(zé)任編輯:龐桂玉 來(lái)源: web前端開(kāi)發(fā)
相關(guān)推薦

2020-07-24 10:00:00

JavaScript執(zhí)行上下文前端

2021-09-07 09:53:42

JavaScript變量提升

2019-03-14 08:00:00

JavaScript執(zhí)行棧前端

2022-09-15 08:01:14

繼承基礎(chǔ)設(shè)施基礎(chǔ)服務(wù)

2017-05-11 14:00:02

Flask請(qǐng)求上下文應(yīng)用上下文

2021-05-27 07:02:05

JavaScript代碼設(shè)施

2012-12-31 10:01:34

SELinuxSELinux安全

2024-03-14 08:11:45

模型RoPELlama

2015-07-08 10:25:05

Javascript上下文作用域

2017-12-17 17:01:23

限界上下文系統(tǒng)模型

2022-10-28 16:24:33

Context上下文鴻蒙

2024-09-30 14:10:00

2025-03-18 08:14:05

2023-07-11 10:02:23

2021-07-26 07:47:36

Cpu上下文進(jìn)程

2025-06-06 08:00:00

上下文管理器Python開(kāi)發(fā)

2024-01-29 08:49:36

RAG模型檢索

2020-06-22 08:41:34

JS語(yǔ)言代碼

2023-05-05 07:41:42

執(zhí)行上下文JavaScript

2010-02-25 17:04:54

WCF實(shí)例上下文
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 久久久久无码国产精品一区 | 亚洲国产二区 | 精品乱码久久久久 | 久久网一区二区三区 | 人妖av | 日韩成人免费 | 污视频免费在线观看 | 欧美日韩国产一区二区三区 | 成年无码av片在线 | 欧美一区成人 | 白浆在线 | 欧美日韩在线免费 | 午夜一区二区三区在线观看 | 欧美一区二区精品 | 九九在线精品视频 | 一区二区三区四区国产 | 久久久.com | 91在线看| 久久精品国产v日韩v亚洲 | 青青草一区 | 污片在线观看 | 久国产视频 | 日日拍夜夜 | 九九亚洲| av日日操 | 国产有码 | 91精品久久久久久久久 | 精品国产欧美一区二区三区成人 | 国产精品国产a | 在线2区 | 97超碰人人草 | 中文成人在线 | 国产精品国产精品国产专区不片 | www.日本在线播放 | 一区二区不卡 | 日韩在线播放第一页 | 四虎影院一区二区 | www.亚洲.com | 一区二区日韩 | 羞羞网站在线免费观看 | 国产成人在线视频播放 |