摘要:聲明變量不存在變量提升。臨時死區,而且不能在聲明之前訪問它。禁止重復聲明相同的變量,否則報錯。不存在變量提升,一旦執行快外就會立即銷毀。聲明不允許修改綁定,但允許修改值,也就是說用創建對象后,可以修改該對象的屬性值。
知識點
1、存在變量提升,實際上var無論在哪里聲明,都會被當做當前的作用域頂部聲明變量。 2、可以重復聲明,后聲明的變量會覆蓋前聲明的變量。
1、不存在變量提升。 2、禁止重復聲明。 3、塊級作用域,只在當前作用域塊有用。 4、臨時死區,而且不能在聲明之前訪問它。
1、const 聲明的是常量,其值一旦確定后不可以修改 2、const 聲明常量時候必須要進行賦值 3、const 不存在變量提升,一旦執行快外就會立即銷毀。 4、const 只能在當前代碼塊級有效, 5、const 不能重復聲明相同常量。 6、const聲明不允許修改綁定,但允許修改值,也就是說用const創建對象后,可以修改該對象的屬性值。一、聲明JavaScript的變量有哪些?
每種編程語言都有變量,聲明變量的方法各不同,在JavaScript里面,最經典的var聲明一個變量,當ECMAScript6出現后,新增了2個聲明變量的方法:let和const,那何時創建變量,用什么聲明變量方法會更好呢?
二、先談談var聲明及變量提示(hoisting)機制var聲明一個變量時候,只需要 var name; 或者聲明賦值var name = "Bob";
實際上var無論在哪里聲明,都會被當做當前的作用域頂部聲明變量。
// var 的變量提升機制 function getValue(condition) { if (condition) { var values = "Bob"; return values; } else { console.log(values); // 這里訪問到values 是undefined,原因下面解釋: return null; } } // 原因解釋:為什么上面的代碼else還能訪問values的值,雖然是undefined // 無論變量values都會被創建,在編譯過程中,JavaScript引擎會將上面的getValue函數修改成這樣: function getValue(condition) { // 重點看這里,變量values的聲明被提升到函數頂部 var values; if (condition) { values = "Bob"; return values; } else { console.log(values); // 所以這里訪問到是聲明過的但未賦值的values,所以是undefined。 return null; } }三、塊級聲明的出現
塊級聲明用于聲明在指定的塊的作用域之外無法訪問的變量
函數內部
塊級中(字符{ }之間的區域)
四、let聲明let聲明變量和var聲明變量,但let有自己的四個特征:
塊級作用域,限制在當前的塊級作用域中,外面作用域無法訪問。
不存在變量提升。
臨時死區,而且不能在聲明之前訪問它。
禁止重復聲明相同的變量,否則報錯。
我們可以把剛才聊到的getValue函數修改一下:
// let 塊級作用域 && 不存在變量提升 function getValue(condition) { if (condition) { // 使用let聲明變量 let values = "Bob"; return values; } else { console.log(values); // 這里報錯: ReferenceError: values is not defined.. // 原因就是用let聲明的變量,是不存在變量提升的, // 而且values變量只能在if{ 這個作用塊里面有效 } 外面是訪問不到的 // 同時,在外面訪問不僅會訪問不到,而且會報錯 return null; } } // let 禁止重復聲明相同變量 function getValue() { var values = "Bob"; let values = {name: "Bob"}; // 使用let聲明變量禁止重復聲明已經有的變量名 // 否則報錯:SyntaxError: Identifier "values" has already been declared }五、const聲明
const 聲明的是常量,其值一旦確定后不可以修改。
const 聲明常量時候必須要進行賦值。
const 不存在變量提升,一旦執行快外就會立即銷毀。
const 只能在當前代碼塊級有效,
const 不能重復聲明相同常量。
const聲明不允許修改綁定,但允許修改值,也就是說用const創建對象后,可以修改該對象的屬性值。
function getValue() { // 聲明一個常量 const USER_NAME = "梁鳳波"; // 禁止重復聲明相同常量,否則報錯:TypeError: Assignment to constant variable. // const USER_NAME = "Bob"; // 記?。篶onst聲明不允許修改綁定,但允許修改值, // 也就是說用const創建對象后,可以修改該對象的屬性值 const STUDYENT = { name: "梁鳳波" }; console.log(`STUDYENT.name = ${STUDYENT.name}`); // STUDYENT.name = 梁鳳波 STUDYENT.name = "Bob"; console.log(`STUDYENT.name = ${STUDYENT.name}`); // STUDYENT.name = Bob }拓展:循環中的塊級作用域綁定
// 在for循環內用var 聲明,在外面訪問到的是for循環后的結果 for (var i = 0; i < 10; i++) { } console.log(`i = ${i}`); // i = 10 // 在for循環內用let 聲明,在外面 訪問不到,塊級作用域問題 for (let i = 0; i < 10; i++) { } console.log(`i = ${i}`); // ReferenceError: i is not defined
// 經過for循環后,在外面訪問i,是直接訪問到了結果i = 10 let funcs = []; for (var i = 0; i < 10; i++) { funcs.push(function () { console.log(i); }) } funcs.forEach(func => { func() // 分別輸出10次10 });
原因:循環里每次迭代同時共享著變量i,循環內部創建的函數全保留相同變量的引用,循環結束時候i的值變為10,所以每次調用console.log(i)時候回輸出數字10
為了解決這個問題,可以在循環中使用立即調用函數表達式(IIFE),以強制生成計數器變量的副本:
// 如果要理想效果,在外面分別輸出 0 ~ 9, // 可以使用閉包暴露出去 let funcs = []; for (var i = 0; i < 10; i++) { funcs.push((function (val) { return function () { console.log(val); } }(i))) } funcs.forEach(func => { func() });
let funcs = []; for (let i = 0; i < 10; i++) { funcs.push(function () { console.log(i); }) } funcs.forEach(func => { func() // 分別輸出 0 ~ 9 });
let 聲明模仿上述示例IIFE所做的一切簡化循環過程,每次迭代循環都會創建一個新變量,并以之前迭代中同名變量的值將其初始化。
let funcs = []; let obj = { a: true, b: true, c: true } for (const key in obj) { funcs.push(function () { console.log(key); }) } funcs.forEach(func => { func() // 分別輸出 a, b, c Authorization });
let和const聲明循環,const循環是不能改變key的值,const 循環應該使用for-in,for-of,其他和let示例一樣,因為每次迭代不會像var循環例子一樣修改已有的綁定,而是會創建一個新綁定。
全局塊級作用域綁定var RegExp = "Bob"; // 即使是全局對象RegExp定義在window,也不能幸免被var聲明覆蓋 console.log(RegExp); // Bob console.log(window.RegExp); // Bob let RegExp = "Bob"; // 用let或const聲明不能覆蓋全局變量,而只能屏蔽它 console.log(RegExp); // Bob console.log(window.RegExp); // undefined console.log(window.RegExp === RegExp); // false const ncz = "Hi!" console.log("ncz" in window); // false最后聊一聊塊級綁定的最佳實踐
默認使用const,只在確實需求改變變量的值使用let,這樣就可以在某種程度上實現代碼的不可變,從而防止默寫錯誤產生。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95298.html
摘要:前言項目地址如果有想要增加的特性,歡迎更新,然后。環境大致結論許多情況下下的特性表現相對更好。 前言 項目 github 地址:https://github.com/DavidCai1993/ES6-benchmark 如果有想要增加的特性 benchmark ,歡迎更新benchmarks/ ,然后 PR 。 環境 CPU: Intel Core(TM) i5-2410M 2.30...
摘要:的翻譯文檔由的維護很多人說,阮老師已經有一本關于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。 JavaScript Promise 迷你書(中文版) 超詳細介紹promise的gitbook,看完再不會promise...... 本書的目的是以目前還在制定中的ECMASc...
摘要:最近買了深入理解的書籍來看,為什么學習這么久還要買這本書呢主要是看到核心團隊成員及的創造者為本書做了序,作為一個粉絲,還是挺看好這本書能給我帶來一個新的升華,而且本書的作者也非常厲害。 使用ES6開發已經有1年多了,以前看的是阮一峰老師的ES6教程,也看過MDN文檔的ES6語法介紹。 最近買了《深入理解ES6》的書籍來看,為什么學習ES6這么久還要買這本書呢?主要是看到Daniel A...
摘要:塊級綁定拓展對象功能解構改進的數組代理和反射附錄小的改變附錄 understanding es6 -- Nicholas C. Zakas 塊級綁定 function 拓展對象功能 解構 symbol Sets and Maps Iterators and Generators class 改進的數組 promise 代理和反射 -- Proxy&Reflection mo...
閱讀 631·2021-11-22 15:32
閱讀 2720·2021-11-19 09:40
閱讀 2313·2021-11-17 09:33
閱讀 1263·2021-11-15 11:36
閱讀 1864·2021-10-11 10:59
閱讀 1475·2019-08-29 16:41
閱讀 1780·2019-08-29 13:45
閱讀 2150·2019-08-26 13:36