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

資訊專欄INFORMATION COLUMN

JavaScript 之執(zhí)行上下文

FrozenMap / 2167人閱讀

摘要:本文就梳理有關(guān)執(zhí)行上下文也叫執(zhí)行環(huán)境的知識(shí)。全局代碼的執(zhí)行上下文棧可以表示為函數(shù)代碼當(dāng)執(zhí)行函數(shù)代碼時(shí),函數(shù)代碼上下文被壓入到執(zhí)行上下文棧中。

本文共 1090 字,讀完只需 4 分鐘
概述

JavaScript 是函數(shù)式編程語言,作用域也是以函數(shù)為單位,那么,這些函數(shù)代碼塊是怎么樣的順序進(jìn)行的呢, JS 的可執(zhí)行代碼又分為 3 種,不同類型的代碼有不一樣的執(zhí)行環(huán)境。本文就梳理有關(guān) JS 執(zhí)行上下文(execution context),也叫執(zhí)行環(huán)境的知識(shí)。

活動(dòng)的執(zhí)行代碼的上下文在語言底層邏輯上構(gòu)成一個(gè)執(zhí)行上下文棧(excution context stack),我們知道,棧有兩個(gè)行為,壓入棧和彈出棧,并且有后進(jìn)先出的特點(diǎn), 最先進(jìn)入的項(xiàng)會(huì)在棧底最后彈出。

不同執(zhí)行環(huán)境的有其相應(yīng)的變量對(duì)象(Variable Object),某個(gè)執(zhí)行環(huán)境的所有可執(zhí)行代碼都執(zhí)行完畢后,該環(huán)境中的變量對(duì)象和函數(shù)定義會(huì)被清除。

函數(shù)代碼會(huì)在執(zhí)行完后清除變量占用的內(nèi)存,全局代碼則會(huì)在關(guān)閉環(huán)境,比如關(guān)閉瀏覽器后清除。

一、代碼類型

JS 中可執(zhí)行的代碼可分為三種類型:

全局代碼

函數(shù)代碼

Eval 代碼

全局代碼

在 web 瀏覽器中,全局執(zhí)行環(huán)境是 window 對(duì)象,所有的全局變量和函數(shù)都是作為 window 的屬性和方法存在。

全局代碼的執(zhí)行上下文棧可以表示為:

ECStack = [
    globalContext
]

函數(shù)代碼

當(dāng)執(zhí)行函數(shù)代碼時(shí),函數(shù)代碼上下文被壓入到執(zhí)行上下文棧中。函數(shù)代碼的執(zhí)行環(huán)境中,有自己的內(nèi)部的定義的變量和聲明。

function foo1() {
    var name1 = "a";
    console.log(name1)
}

function foo2(){
    var name2 = "b";
    console.log(name2)
}

foo1();
foo2();

上面的執(zhí)行上下文可以表示為:

ECStack = [
    globalContext
];

ECStack.push( functionContext);
ECStack.pop();
ECStack.push( functionContext);
ECStack.pop();

一個(gè)函數(shù),可能有多個(gè)執(zhí)行上下文,每個(gè)函數(shù)的調(diào)用都會(huì)產(chǎn)生新的上下文。

function foo() {
    ...
}

foo("a");
foo("b");
foo("c");

eval 代碼

eval 關(guān)鍵字接受一個(gè)字符串作為參數(shù),并將其作為書寫文字上下文的代碼。

function foo(str, a) {
    eval( str );  // 聲明一個(gè)新變量
    console.log(a, b);
}
var b = 123;

foo("var b = 456 ", 123) // 123, 456

以上代碼引用《你不知道的 JavaScript》的例子,eval 函數(shù)中的字符串,被當(dāng)做可執(zhí)行代碼,最后在 foo 函數(shù)中聲明了 b 變量,并覆蓋了 foo 函數(shù)外部的 b 變量。

eval 函數(shù)和 JS 的詞法作用域的行為,會(huì)造成變量環(huán)境和執(zhí)行上下文的混亂,盡量別使用它。

二、執(zhí)行上下文棧

前面其實(shí)已經(jīng)提到很多關(guān)于執(zhí)行上下文棧的內(nèi)容,簡(jiǎn)而言之,JS 在遇到全局代碼,函數(shù)代碼,eval 代碼時(shí),會(huì)創(chuàng)建相應(yīng)的執(zhí)行上下文,不同的上下文,有其變量對(duì)象(variable object: VO)和作用域。

看這一段代碼:

function func3() {
    console.log("fun3")
}

function func2() {
    func3();
}

function func1() {
    func2();
}

func1();

以上代碼引用自冴羽的github,代碼順序用執(zhí)行上下文棧來表示就是:

ECStack.push(globalContext);

// 調(diào)用 func1(), 進(jìn)入 func1 執(zhí)行環(huán)境
ECStack.push( functionContext);

// func1中調(diào)用了 func2,進(jìn)入 func2 的執(zhí)行上下文
ECStack.push( functionContext);

// func2 調(diào)用 func3, 進(jìn)入 func3 的執(zhí)行上下文
ECStack.push( functionContext);

// func3 執(zhí)行完畢,退出 func3 執(zhí)行環(huán)境
ECStack.pop();

// func2 執(zhí)行完畢,退出 func2 執(zhí)行環(huán)境
ECStack.pop();

// func1 執(zhí)行完畢,退出 func1 執(zhí)行環(huán)境
ECStack.pop();

函數(shù)代碼執(zhí)行完畢后,執(zhí)行上下文棧底只剩下全局代碼上下文 globalContext, 直到關(guān)閉瀏覽器才會(huì)徹底清空?qǐng)?zhí)行上下文棧。

總結(jié)

代碼在執(zhí)行時(shí)會(huì)創(chuàng)建由不同作用域構(gòu)成的作用域鏈作用域鏈保證 JS 中的變量和函數(shù)都能夠有序地訪問和執(zhí)行。

如果是函數(shù)代碼,則將其 活動(dòng)對(duì)象 作為變量對(duì)象,活動(dòng)對(duì)象最開始時(shí)只包含一個(gè)對(duì)象,即 arguments 對(duì)象。

后面的文章會(huì)介紹變量對(duì)象(VO)和作用域鏈的具體內(nèi)容,敬請(qǐng)期待吧。

博客內(nèi)容源自個(gè)人公眾號(hào),專注分享原創(chuàng)文章,歡迎關(guān)注。

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

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

相關(guān)文章

  • JavaScript深入執(zhí)行下文

    摘要:深入系列第七篇,結(jié)合之前所講的四篇文章,以權(quán)威指南的為例,具體講解當(dāng)函數(shù)執(zhí)行的時(shí)候,執(zhí)行上下文棧變量對(duì)象作用域鏈?zhǔn)侨绾巫兓摹G把栽谏钊胫畧?zhí)行上下文棧中講到,當(dāng)代碼執(zhí)行一段可執(zhí)行代碼時(shí),會(huì)創(chuàng)建對(duì)應(yīng)的執(zhí)行上下文。 JavaScript深入系列第七篇,結(jié)合之前所講的四篇文章,以權(quán)威指南的demo為例,具體講解當(dāng)函數(shù)執(zhí)行的時(shí)候,執(zhí)行上下文棧、變量對(duì)象、作用域鏈?zhǔn)侨绾巫兓摹?前言 在《Jav...

    gougoujiang 評(píng)論0 收藏0
  • JavaScript深入作用域鏈

    摘要:下面,讓我們以一個(gè)函數(shù)的創(chuàng)建和激活兩個(gè)時(shí)期來講解作用域鏈?zhǔn)侨绾蝿?chuàng)建和變化的。這時(shí)候執(zhí)行上下文的作用域鏈,我們命名為至此,作用域鏈創(chuàng)建完畢。 JavaScript深入系列第五篇,講述作用鏈的創(chuàng)建過程,最后結(jié)合著變量對(duì)象,執(zhí)行上下文棧,讓我們一起捋一捋函數(shù)創(chuàng)建和執(zhí)行的過程中到底發(fā)生了什么? 前言 在《JavaScript深入之執(zhí)行上下文棧》中講到,當(dāng)JavaScript代碼執(zhí)行一段可執(zhí)行代...

    waltr 評(píng)論0 收藏0
  • JavaScript深入閉包

    摘要:深入系列第八篇,介紹理論上的閉包和實(shí)踐上的閉包,以及從作用域鏈的角度解析經(jīng)典的閉包題。定義對(duì)閉包的定義為閉包是指那些能夠訪問自由變量的函數(shù)。 JavaScript深入系列第八篇,介紹理論上的閉包和實(shí)踐上的閉包,以及從作用域鏈的角度解析經(jīng)典的閉包題。 定義 MDN 對(duì)閉包的定義為: 閉包是指那些能夠訪問自由變量的函數(shù)。 那什么是自由變量呢? 自由變量是指在函數(shù)中使用的,但既不是函數(shù)參數(shù)也...

    caige 評(píng)論0 收藏0
  • JavaScript深入執(zhí)行下文

    摘要:深入系列第三篇,講解執(zhí)行上下文棧的是如何執(zhí)行的,也回答了第二篇中的略難的思考題。 JavaScript深入系列第三篇,講解執(zhí)行上下文棧的是如何執(zhí)行的,也回答了第二篇中的略難的思考題。 順序執(zhí)行? 如果要問到 JavaScript 代碼執(zhí)行順序的話,想必寫過 JavaScript 的開發(fā)者都會(huì)有個(gè)直觀的印象,那就是順序執(zhí)行,畢竟: var foo = function () { ...

    codecraft 評(píng)論0 收藏0
  • JavaScript專題遞歸

    摘要:專題系列第十八篇,講解遞歸和尾遞歸定義程序調(diào)用自身的編程技巧稱為遞歸。然而非尾調(diào)用函數(shù),就會(huì)創(chuàng)建多個(gè)執(zhí)行上下文壓入執(zhí)行上下文棧。所以我們只用把階乘函數(shù)改造成一個(gè)尾遞歸形式,就可以避免創(chuàng)建那么多的執(zhí)行上下文。 JavaScript 專題系列第十八篇,講解遞歸和尾遞歸 定義 程序調(diào)用自身的編程技巧稱為遞歸(recursion)。 階乘 以階乘為例: function factorial(n...

    asoren 評(píng)論0 收藏0
  • 【進(jìn)階1-2期】JavaScript深入執(zhí)行下文棧和變量對(duì)象

    摘要:本計(jì)劃一共期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)階計(jì)劃,點(diǎn)擊查看前端進(jìn)階的破冰之旅本期推薦文章深入之執(zhí)行上下文棧和深入之變量對(duì)象,由于微信不能訪問外鏈,點(diǎn)擊閱讀原文就可以啦。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開始前端進(jìn)階的第一期,本周的主題是調(diào)用堆棧,今天是第二天。 本計(jì)劃一共28期,每期...

    Richard_Gao 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<