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