搜尋
首頁web前端js教程JavaScript塊級作用域的實作原理(圖文詳解)

本篇文章帶給大家關於JavaScript中區塊級作用域的實作原理相關知識,在ES6之前,區塊級作用域是不被JavaScript所支援的,JavaScript是透過什麼支援了區塊級作用域的呢?本文將講解塊級作用域的底層實現原理,希望對大家有幫助。

JavaScript塊級作用域的實作原理(圖文詳解)

作用域與執行上下文

很多人覺得作用域與執行上下文是一個概念,這種想法是完全錯誤的!

作用域

作用域在函數宣告時就已經確定了,作用域是據名稱來找出變數的一套規則,也就是確定了目前執行程式碼對變數的存取權限。 JavaScript一共支援三種類型的作用域,它們分別是:全域作用域、函數作用域、區塊層級作用域。

執行上下文

執行上下文是js引擎從解釋到運行中間預編譯時對執行做的準備工作,創建了當前區域的執行環境,這個執行環境就是執行上下文。

執行堆疊

呼叫堆疊用來裝js程式碼中的各種執行上下文,是js引擎追蹤函數執行的一個機制。

以下面的程式碼為例:

console.log(1);
function pFn() {
    console.log(2);
    (function cFn() {
        console.log(3);
    }());
    console.log(4);
}
pFn();
console.log(5);
//输出:1 2 3 4 5

先有全域環境下的執行上下文,呼叫pFn後將函數環境pFn的執行上下文壓入堆疊中,由於pFn中執行了cFn函數,所以繼續壓入cFn函數的執行上下文,執行完畢後依序出棧。

全域上下文只有應用程式退出前才會被銷毀,例如關閉網頁或退出瀏覽器

JavaScript塊級作用域的實作原理(圖文詳解)

javascript 是如何支援區塊級作用域的

我們知道在js中由於初始設計的不規範,用var關鍵字定義變數會導致變數提升等一系列問題,但為了保持相容性,我們也不得不對var宣告變數保留支持,那麼:JavaScript是如何做到既要支援變數提升,又要支援區塊級作用域的呢?

我們以下面這段程式碼為例:

function foo() {
   var a = 1;
   let b = 2;
   {
   let b = 3;
   var c = 4;
   let d = 5;
   console.log(a);
   console.log(b);
   }
   console.log(b);
   console.log(c);
   console.log(d);
}

首先函數內部透過var宣告的變數被存放到變數環境中,透過let宣告的變數在預編譯階段被存放到詞法環境中,當然在函數體內部塊作用域中let宣告的變數並沒有被存放到詞法環境。

JavaScript塊級作用域的實作原理(圖文詳解)

繼續執行程式碼,當執行到程式碼區塊裡面時,變數環境中的a的值已經設定為1,詞法環境中b的值已經設定成了2,注意用let宣告的變數b和d此時不是underfined而是uninitialized未初始化

JavaScript塊級作用域的實作原理(圖文詳解)

#最後當函數體內區塊作用域執行結束之後,其內部變量就會從詞法環境的棧頂彈出

JavaScript塊級作用域的實作原理(圖文詳解)

總結

#我們可以知道上面問題的答案:

用let 宣告出來的變數中都會在詞法環境中存放,塊級作用域是透過詞法環境的堆疊結構來實現的,而變數提升是透過變數環境來實現的,兩者結合同時支援變數提升和區塊級作用域

以及變數的查找方式:

從詞法環境的作用域堆疊頂開始向下查找,如果找到了就回傳值,如果找不到,就繼續去變數環境中找

相關推薦:javascript學習教學

#

以上是JavaScript塊級作用域的實作原理(圖文詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:掘金。如有侵權,請聯絡admin@php.cn刪除
es6数组怎么去掉重复并且重新排序es6数组怎么去掉重复并且重新排序May 05, 2022 pm 07:08 PM

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

JavaScript的Symbol类型、隐藏属性及全局注册表详解JavaScript的Symbol类型、隐藏属性及全局注册表详解Jun 02, 2022 am 11:50 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

原来利用纯CSS也能实现文字轮播与图片轮播!原来利用纯CSS也能实现文字轮播与图片轮播!Jun 10, 2022 pm 01:00 PM

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

JavaScript对象的构造函数和new操作符(实例详解)JavaScript对象的构造函数和new操作符(实例详解)May 10, 2022 pm 06:16 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

JavaScript面向对象详细解析之属性描述符JavaScript面向对象详细解析之属性描述符May 27, 2022 pm 05:29 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

javascript怎么移除元素点击事件javascript怎么移除元素点击事件Apr 11, 2022 pm 04:51 PM

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

整理总结JavaScript常见的BOM操作整理总结JavaScript常见的BOM操作Jun 01, 2022 am 11:43 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

foreach是es6里的吗foreach是es6里的吗May 05, 2022 pm 05:59 PM

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境