這篇文章帶給大家的內容是關於es6塊級綁定中let and const的詳細分析,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
變數宣告一直是js工作中最微妙的一部分,它不像C語言一樣,變數總是在被它創建的時候聲明,js語言可以允許你在你需要宣告變數的時候進行聲明。
var let const 之變數宣告
var 宣告與變數提升。
當我們使用var關鍵字進行變數宣告的時候,無論變數宣告的位置在哪裡,都會被是為宣告於所在的函數的頂部(如果不在函數內的話,則視為在全域作用域的頂部)這就是所謂的變數提升(hoisting)
var提升如下:
function getValue(condition) { if (condition) { var value = "blue"; // 其他代码 return value; } else { // value 在此处可访问,值为 undefined return null; } // value 在此处可访问,值为 undefined }
區塊級宣告let
區塊級宣告也就是讓所宣告的變數在指定的作用域外無法被存取到,區塊級作用域在如下情況下被建立
- 在一個函數內部,
- 在一個程式碼區塊(由一對花括號包裹)內部
let宣告的語法和var宣告一致,由於let宣告不會將變數提升到函數頂部,因此我們需要手動將let宣告放置到頂部,以便讓變數在整個程式碼塊內部可用。
如下所示:
function getValue(condition) { if (condition) { let value = "blue"; // 其他代码 return value; } else { // value 在此处不可用 return null; } // value 在此处不可用 }
禁止重複標識
如果一個識別碼已經在程式碼內部定義,重複進行let宣告會錯誤
var a = 30; //报错 let a = 30;
a變數被宣告了兩次:一次使用var ,另一次使用let 。因為 let 不能在同一作用域內重複宣告一個已有標識符,而此處的 let 宣告會拋出錯誤。另一方面,在嵌套的作用域內使用let 宣告一個同名的新變量,則不會拋出錯誤,以下程式碼對此進行了演示:
var count = 30; // 不会抛出错误 if (condition) { let count = 40; // 其他代码 }
這段程式碼中不會拋錯,關鍵點在於let在同一層級程式碼區塊中重複宣告會報錯
const常數宣告
在es6中可以使用const語法進行宣告。使用const宣告的變數會被認為是常數(constant),意味著他們的值在被設定完成後既不能再被改變。正因為如此,所有的const的變數都需要在宣告時進行初始化,
// 有效的常量 const maxItems = 30; // 语法错误:未进行初始化 const name;
maxItems 變數被初始化了,因此它的 const 宣告能正常起效。而 name 變數沒有被初始化,導致在試圖執行這段程式碼時拋出了錯誤。 const宣告會組織變數綁定和自生值的修改,這表示const宣告不會組織變數成員的修改。例如:
const person = { name: "Nicholas" }; // 工作正常 person.name = "Greg"; // 抛出错误 person = { name: "Greg" };
const宣告和let宣告的比較
首先他們都是區塊層級宣告,這表示常數在宣告它們的語句區塊外是無法被存取的,並且宣告也不會被提升,範例如下:
if (condition) { const maxItems = 5; // 其他代码 } // maxItems 在此处无法访问
它們在統一級作用域中重複宣告時會導致拋出錯誤
暫時性死區
當我們使用let或const 進行宣告的時候,在到達宣告處之前都是無法存取的,如果我們試圖存取會導致一個引用錯誤。出項這個問題是因為暫時性死區
當JS 引擎檢視接下來的程式碼區塊並發現變數宣告時,它會在面對var 的情況下將宣告提升到函數或全域作用域的頂部,而面對let 或const 時會將聲明放在暫時性死區內。任何在暫時性死區內存取變數的企圖都會導致「運行時」錯誤(runtime error)。只有當執行到變數的宣告語句時,變數才會從暫時性死區內移除並且可以安全使用。
循環中的區塊級綁定
for (var i = 0; i <p>輸出的結果並不是預期的值而是10;是因為var宣告導致的變數的提升。聰明的你一定會想到使用區塊級綁定來進行變數宣告</p><pre class="brush:php;toolbar:false">for (let i = 0; i <p>i在此處是不是會正常輸出呢,其實不會,在這個例子中會導致報錯,為什麼呢?因為i在此處不可訪問。本例中的變數 i 僅在 for 迴圈內部可用,一旦迴圈結束,變數在任意位置都不可存取。 </p><p>我們在來看看程式碼</p><pre class="brush:php;toolbar:false">var funcs = []; for (var i = 0; i <p>你原本可能預期這段程式碼會輸出 0 到 9 的數值,但它卻在同一行將數值 10 輸出了十次。這是因為變數 i 在循環的每次迭代中都被共享了,這意味著在循環內創建的那些函數都擁有對於同一變數的引用。在迴圈結束後,變數 i 的值會是 10 ,因此當 console.log(i) 被呼叫時,<br>每次都會印出 10 。 </p><p>為了修正這個問題,開發者在循環內使用立即呼叫函數表達式(IIFEs),以便在每次迭代中強制建立變數的一個新副本,範例如下:</p><pre class="brush:php;toolbar:false">var funcs = []; for (var i = 0; i <h3 id="循環內的let-宣告">循環內的let 宣告</h3><p>let 宣告透過有效模仿上例中IIFE 的作用而簡化了循環。在每次迭代中,都會建立一個新的<br>同名變數並對其進行初始化。這意味著你可以完全省略 IIFE 而獲得預期的結果,就像這樣</p><pre class="brush:php;toolbar:false">var funcs = []; for (let i = 0; i <p>我们是否会想到这个问题:为什么同样的代码使用let声明会导致不一样的结果呢?<br><strong>在循环中let声明每次都创建了一个新的i变量,因此在循环内部创建的函数获得了各自的i副本,而每个i副本的值都会在每次的循环迭代声明变量的时候确定了</strong></p><pre class="brush:php;toolbar:false">var funcs = [], object = { a: true, b: true, c: true }; for (let key in object) { funcs.push(function() { console.log(key); }); } funcs.forEach(function(func) { func(); // 依次输出 "a"、 "b"、 "c" });
本例中的 for-in 循环体现出了与 for 循环相同的行为。每次循环,一个新的 key 变量绑定就被创建,因此每个函数都能够拥有它自身的 key 变量副本,结果每个函数都输出了一个不同的值。而如果使用 var 来声明 key ,则所有函数都只会输出 "c" 。
let 声明在循环内部的行为是在规范中特别定义的,而与不提升变量声明的特征没有必然联系。事实上,在早期 let 的实现中并没有这种行为,它是后来才添加的。
循环内的常量声明
虽然es6没有明确的规范我们不能在for循环中使用const声明,然而它会根据循环方式的不同而有不同的行为,我们可以在初始化时使用const,但是当循环试图改变变量的值的时候会抛出错误,例如:
var funcs = []; // 在一次迭代后抛出错误 for (const i = 0; i <p>在此代码中, i 被声明为一个常量。循环的第一次迭代成功执行,此时 i 的值为 0 。在<br>i++ 执行时,一个错误会被抛出,因为该语句试图更改常量的值。因此,在循环中你只能使<br>用 const 来声明一个不会被更改的变量<br>而另一方面, const 变量在 for-in 或 for-of 循环中使用时,与 let 变量效果相同。因<br>此下面代码不会导致出错:</p><pre class="brush:php;toolbar:false">var funcs = [], object = { a: true, b: true, c: true }; // 不会导致错误 for (const key in object) { funcs.push(function() { console.log(key); }); } funcs.forEach(function(func) { func(); // 依次输出 "a"、 "b"、 "c" });
这段代码与“循环内的 let 声明”小节的第二个例子几乎完全一样,唯一的区别是 key 的值在
循环内不能被更改。 const 能够在 for-in 与 for-of 循环内工作,是因为循环为每次迭
代创建了一个新的变量绑定,而不是试图去修改已绑定的变量的值(就像使用了 for 而不是
for-in 的上个例子那样)。
全局块级绑定
let 与 const 不同于 var 的另一个方面是在全局作用域上的表现。当在全局作用域上使用 var 时,它会创建一个新的全局变量,并成为全局对象(在浏览器中是 window )的一
个属性。
总结
let和const块级作用域的引入,能够使我们减少很多无心的错误,它们的一个副作用,是不能在变量声明位置之前访问它们
块级绑定当前的最佳实践就是:在默认情况下使用 const ,而只在你知道变量值需要被更改的情况下才使用 let 。这在代码中能确保基本层次的不可变性,有助于防止某些类型的错误。
本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的JavaScript视频教程栏目!
以上是es6塊級綁定中let and const的詳細分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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

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

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

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

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

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

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

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


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver Mac版
視覺化網頁開發工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。