摘要:首次運(yùn)行代碼時(shí),會(huì)創(chuàng)建一個(gè)全局執(zhí)行上下文并到當(dāng)前的執(zhí)行棧中。執(zhí)行上下文的創(chuàng)建執(zhí)行上下文分兩個(gè)階段創(chuàng)建創(chuàng)建階段執(zhí)行階段創(chuàng)建階段確定的值,也被稱為。
(關(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期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)階計(jì)劃,點(diǎn)擊查看前端進(jìn)階的破冰之旅
本期推薦文章理解JavaScript 中的執(zhí)行上下文和執(zhí)行棧,由于微信不能訪問外鏈,點(diǎn)擊閱讀原文就可以啦。
推薦理由首先這是一篇譯文,文章翻譯的挺好,詳細(xì)介紹了執(zhí)行上下文的類型和創(chuàng)建過程,對(duì)于理解JS運(yùn)行機(jī)制有極大的幫助,特別是從另一個(gè)角度介紹了ES5/6情況下變量提升的情況和原因。
閱讀筆記執(zhí)行上下文是當(dāng)前 JavaScript 代碼被解析和執(zhí)行時(shí)所在環(huán)境的抽象概念。
執(zhí)行上下文的類型執(zhí)行上下文總共有三種類型
全局執(zhí)行上下文:只有一個(gè),瀏覽器中的全局對(duì)象就是 window 對(duì)象,this 指向這個(gè)全局對(duì)象。
函數(shù)執(zhí)行上下文:存在無(wú)數(shù)個(gè),只有在函數(shù)被調(diào)用的時(shí)候才會(huì)被創(chuàng)建,每次調(diào)用函數(shù)都會(huì)創(chuàng)建一個(gè)新的執(zhí)行上下文。
Eval 函數(shù)執(zhí)行上下文: 指的是運(yùn)行在 eval 函數(shù)中的代碼,很少用而且不建議使用。
執(zhí)行棧執(zhí)行棧,也叫調(diào)用棧,具有 LIFO(后進(jìn)先出)結(jié)構(gòu),用于存儲(chǔ)在代碼執(zhí)行期間創(chuàng)建的所有執(zhí)行上下文。
首次運(yùn)行JS代碼時(shí),會(huì)創(chuàng)建一個(gè)全局執(zhí)行上下文并Push到當(dāng)前的執(zhí)行棧中。每當(dāng)發(fā)生函數(shù)調(diào)用,引擎都會(huì)為該函數(shù)創(chuàng)建一個(gè)新的函數(shù)執(zhí)行上下文并Push到當(dāng)前執(zhí)行棧的棧頂。
根據(jù)執(zhí)行棧LIFO規(guī)則,當(dāng)棧頂函數(shù)運(yùn)行完成后,其對(duì)應(yīng)的函數(shù)執(zhí)行上下文將會(huì)從執(zhí)行棧中Pop出,上下文控制權(quán)將移到當(dāng)前執(zhí)行棧的下一個(gè)執(zhí)行上下文。
執(zhí)行上下文的創(chuàng)建執(zhí)行上下文分兩個(gè)階段創(chuàng)建:1)創(chuàng)建階段; 2)執(zhí)行階段
創(chuàng)建階段1、確定 this 的值,也被稱為 This Binding。
2、LexicalEnvironment(詞法環(huán)境) 組件被創(chuàng)建。
3、VariableEnvironment(變量環(huán)境) 組件被創(chuàng)建。
直接看偽代碼可能更加直觀
ExecutionContext = { ThisBinding =, // 確定this LexicalEnvironment = { ... }, // 詞法環(huán)境 VariableEnvironment = { ... }, // 變量環(huán)境 }
全局執(zhí)行上下文中,this 的值指向全局對(duì)象,在瀏覽器中this 的值指向 window 對(duì)象,而在nodejs中指向這個(gè)文件的module對(duì)象。
函數(shù)執(zhí)行上下文中,this 的值取決于函數(shù)的調(diào)用方式。具體有:默認(rèn)綁定、隱式綁定、顯式綁定(硬綁定)、new綁定、箭頭函數(shù),具體內(nèi)容會(huì)在【this全面解析】部分詳解。
詞法環(huán)境有兩個(gè)組成部分
1、環(huán)境記錄:存儲(chǔ)變量和函數(shù)聲明的實(shí)際位置
2、對(duì)外部環(huán)境的引用:可以訪問其外部詞法環(huán)境
詞法環(huán)境有兩種類型
1、全局環(huán)境:是一個(gè)沒有外部環(huán)境的詞法環(huán)境,其外部環(huán)境引用為 null。擁有一個(gè)全局對(duì)象(window 對(duì)象)及其關(guān)聯(lián)的方法和屬性(例如數(shù)組方法)以及任何用戶自定義的全局變量,this 的值指向這個(gè)全局對(duì)象。
2、函數(shù)環(huán)境:用戶在函數(shù)中定義的變量被存儲(chǔ)在環(huán)境記錄中,包含了arguments 對(duì)象。對(duì)外部環(huán)境的引用可以是全局環(huán)境,也可以是包含內(nèi)部函數(shù)的外部函數(shù)環(huán)境。
直接看偽代碼可能更加直觀
GlobalExectionContext = { // 全局執(zhí)行上下文 LexicalEnvironment: { // 詞法環(huán)境 EnvironmentRecord: { // 環(huán)境記錄 Type: "Object", // 全局環(huán)境 // 標(biāo)識(shí)符綁定在這里 outer:// 對(duì)外部環(huán)境的引用 } } FunctionExectionContext = { // 函數(shù)執(zhí)行上下文 LexicalEnvironment: { // 詞法環(huán)境 EnvironmentRecord: { // 環(huán)境記錄 Type: "Declarative", // 函數(shù)環(huán)境 // 標(biāo)識(shí)符綁定在這里 // 對(duì)外部環(huán)境的引用 outer: } }
變量環(huán)境也是一個(gè)詞法環(huán)境,因此它具有上面定義的詞法環(huán)境的所有屬性。
在 ES6 中,詞法 環(huán)境和 變量 環(huán)境的區(qū)別在于前者用于存儲(chǔ)函數(shù)聲明和變量( let 和 const )綁定,而后者僅用于存儲(chǔ)變量( var )綁定。
使用例子進(jìn)行介紹
let a = 20; const b = 30; var c; function multiply(e, f) { var g = 20; return e * f * g; } c = multiply(20, 30);
執(zhí)行上下文如下所示
GlobalExectionContext = { ThisBinding:, LexicalEnvironment: { EnvironmentRecord: { Type: "Object", // 標(biāo)識(shí)符綁定在這里 a: < uninitialized >, b: < uninitialized >, multiply: < func > } outer: }, VariableEnvironment: { EnvironmentRecord: { Type: "Object", // 標(biāo)識(shí)符綁定在這里 c: undefined, } outer: } } FunctionExectionContext = { ThisBinding: , LexicalEnvironment: { EnvironmentRecord: { Type: "Declarative", // 標(biāo)識(shí)符綁定在這里 Arguments: {0: 20, 1: 30, length: 2}, }, outer: }, VariableEnvironment: { EnvironmentRecord: { Type: "Declarative", // 標(biāo)識(shí)符綁定在這里 g: undefined }, outer: } }
變量提升的原因:在創(chuàng)建階段,函數(shù)聲明存儲(chǔ)在環(huán)境中,而變量會(huì)被設(shè)置為 undefined(在 var 的情況下)或保持未初始化(在 let 和 const 的情況下)。所以這就是為什么可以在聲明之前訪問 var 定義的變量(盡管是 undefined ),但如果在聲明之前訪問 let 和 const 定義的變量就會(huì)提示引用錯(cuò)誤的原因。這就是所謂的變量提升。
執(zhí)行階段此階段,完成對(duì)所有變量的分配,最后執(zhí)行代碼。
如果 Javascript 引擎在源代碼中聲明的實(shí)際位置找不到 let 變量的值,那么將為其分配 undefined 值。
參考理解 Javascript 執(zhí)行上下文和執(zhí)行棧往期文章查看
【進(jìn)階1-1期】理解JavaScript 中的執(zhí)行上下文和執(zhí)行棧
【進(jìn)階1-2期】JavaScript深入之執(zhí)行上下文棧和變量對(duì)象
【進(jìn)階1-3期】JavaScript深入之內(nèi)存空間詳細(xì)圖解
【進(jìn)階1-4期】JavaScript深入之帶你走進(jìn)內(nèi)存機(jī)制制
【進(jìn)階1-5期】JavaScript深入之4類常見內(nèi)存泄漏及如何避免
【進(jìn)階2-1期】深入淺出圖解作用域鏈和閉包
每周計(jì)劃安排每周面試重難點(diǎn)計(jì)劃如下,如有修改會(huì)通知大家。每周一期,為期半年,準(zhǔn)備明年跳槽的小伙伴們可以把本公眾號(hào)置頂了。
【進(jìn)階1期】 調(diào)用堆棧
【進(jìn)階2期】 作用域閉包
【進(jìn)階3期】 this全面解析
【進(jìn)階4期】 深淺拷貝原理
【進(jìn)階5期】 原型Prototype
【進(jìn)階6期】 高階函數(shù)
【進(jìn)階7期】 事件機(jī)制
【進(jìn)階8期】 Event Loop原理
【進(jìn)階9期】 Promise原理
【進(jìn)階10期】Async/Await原理
【進(jìn)階11期】防抖/節(jié)流原理
【進(jìn)階12期】模塊化詳解
【進(jìn)階13期】ES6重難點(diǎn)
【進(jìn)階14期】計(jì)算機(jī)網(wǎng)絡(luò)概述
【進(jìn)階15期】瀏覽器渲染原理
【進(jìn)階16期】webpack配置
【進(jìn)階17期】webpack原理
【進(jìn)階18期】前端監(jiān)控
【進(jìn)階19期】跨域和安全
【進(jìn)階20期】性能優(yōu)化
【進(jìn)階21期】VirtualDom原理
【進(jìn)階22期】Diff算法
【進(jìn)階23期】MVVM雙向綁定
【進(jìn)階24期】Vuex原理
【進(jìn)階25期】Redux原理
【進(jìn)階26期】路由原理
【進(jìn)階27期】VueRouter源碼解析
【進(jìn)階28期】ReactRouter源碼解析
交流本人Github鏈接如下,歡迎各位Star
http://github.com/yygmind/blog
我是木易楊,網(wǎng)易高級(jí)前端工程師,跟著我每周重點(diǎn)攻克一個(gè)前端面試重難點(diǎn)。接下來(lái)讓我?guī)阕哌M(jìn)高級(jí)前端的世界,在進(jìn)階的路上,共勉!
如果你想加群討論每期面試知識(shí)點(diǎn),公眾號(hào)回復(fù)[加群]即可
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/99543.html
摘要:本計(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期,每期...
摘要:使用上一篇文章的例子來(lái)說明下自由變量進(jìn)階期深入淺出圖解作用域鏈和閉包訪問外部的今天是今天是其中既不是參數(shù),也不是局部變量,所以是自由變量。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第7天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)階計(jì)...
摘要:進(jìn)階期理解中的執(zhí)行上下文和執(zhí)行棧進(jìn)階期深入之執(zhí)行上下文棧和變量對(duì)象但是今天補(bǔ)充一個(gè)知識(shí)點(diǎn)某些情況下,調(diào)用堆棧中函數(shù)調(diào)用的數(shù)量超出了調(diào)用堆棧的實(shí)際大小,瀏覽器會(huì)拋出一個(gè)錯(cuò)誤終止運(yù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)用堆棧,今天是第3天。 本計(jì)劃一共28期,每期重點(diǎn)攻...
摘要:引擎對(duì)堆內(nèi)存中的對(duì)象進(jìn)行分代管理新生代存活周期較短的對(duì)象,如臨時(shí)變量字符串等。內(nèi)存泄漏對(duì)于持續(xù)運(yùn)行的服務(wù)進(jìn)程,必須及時(shí)釋放不再用到的內(nèi)存。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開始前端進(jìn)階的第一期,本周的主題是調(diào)用堆棧,今天是第4天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)階計(jì)劃...
摘要:閉包面試題解由于作用域鏈機(jī)制的影響,閉包只能取得內(nèi)部函數(shù)的最后一個(gè)值,這引起的一個(gè)副作用就是如果內(nèi)部函數(shù)在一個(gè)循環(huán)中,那么變量的值始終為最后一個(gè)值。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第8天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了...
閱讀 2858·2021-11-17 09:33
閱讀 4571·2021-09-22 15:57
閱讀 2942·2019-08-30 14:16
閱讀 3196·2019-08-29 14:07
閱讀 2472·2019-08-26 11:55
閱讀 3511·2019-08-23 17:07
閱讀 1791·2019-08-23 16:50
閱讀 2643·2019-08-23 16:08