摘要:塊級聲明塊級聲明是用于聲明在指定塊的作用域之外無法訪問的變量。美元符號可以放到任何一個位置,甚至多帶帶一個美元符號。塊級函數(shù)從開始,在嚴(yán)格模式下,塊里的函數(shù)作用域?yàn)檫@個塊。
持續(xù)更新的github筆記,鏈接地址:Front-End-Basics
此篇文章的筆記地址:字符到底發(fā)生了什么變化
ES6走走看看系列,特別鳴謝奇舞讀書會~
塊級作用域又稱詞法作用域,存在于:函數(shù)內(nèi)部(函數(shù)作用域)
塊中(字符 { 和 } 之間的區(qū)域)
注意:ES6允許塊級作用域任意嵌套
{{{{{{let text = "Hello World!"}}}}}}
因?yàn)橛辛藟K級作用域,然后我們才有繼續(xù)往下聊的可能。
1、 塊級聲明塊級聲明是用于聲明在指定塊的作用域之外無法訪問的變量。
2、 let聲明:用來聲明一個塊級作用域變量1、 聲明的變量具有塊級作用域的特性
// 例子 function getValue (condition) { if (condition) { let value = "blue"; return value; } console.log(value) // 報錯 value is not defined } getValue()
2、 在同一個作用域內(nèi)不能使用let聲明同名的變量
// 不管是var,const或者let,新的let聲明之前同名的變量,都會報錯 var count = 30; let count = 40; // 報錯 Identifier "count" has already been declared // 函數(shù)形參和函數(shù)內(nèi)部的let聲明變量重名,報錯 function test(value) { let value = 3; } test() // 報錯 Identifier "value" has already been declared // 在不同的作用域聲明的變量重名是沒問題的 let count = 30; if(true) { let count = 40; // 不同的作用域,不會報錯 }
3、 聲明沒有預(yù)解析,不存在變量提升,有“臨時死區(qū)”(TDZ)
從塊的開始到變量聲明這段的區(qū)域被稱為臨時死區(qū),ES6明確規(guī)定,如果區(qū)塊中存在let和const命令,則這個區(qū)塊對這些命令聲明的變量從一開始就形成封閉作用域,只要在聲明之前就使用這些變量(賦值,引用等等),就會報錯。
if(true) { console.log(typeof value); // 報錯 value is not defined let value = "blue"; }
注意:TDZ是區(qū)域是“塊開始”到“變量聲明”,下面的例子不報錯
// typeof 說是相對安全,確實(shí)是,永遠(yuǎn)拿不到想要的結(jié)果 console.log(typeof value); // 打印 undefined,沒有報錯 if(true) { let value = "red"; }3、 const聲明:聲明常量(如PI),值一旦被設(shè)定后不可更改
1、 常量聲明的值是不可變的
注意:const聲明的對象不允許修改綁定,但可以修改該對象的屬性值。
const number = 6; number = 5; // 報錯 Assignment to constant variable const obj = {number: 1}; obj.number = 2; // 不報錯 obj = {number: 3}; // 報錯 Assignment to constant variable
2、 因?yàn)槌A柯暶骱笾稻筒豢筛牧耍月暶鲿r必須賦值
// 有效的常量 const count = 30; // 報錯 Missing initializer in const declaration const name;
3、 聲明的常量具有塊級作用域的特性
if(true) { const number = 5; } console.log(number) // 報錯 number is not defined
4、 在同一個作用域內(nèi)不能使用const聲明同名的變量
var message = "Hello"; let age = 25; // 這兩條語句都會報錯 const message = "Good"; const age = 30;
5、 聲明沒有預(yù)解析,不存在變量提升,有“臨時死區(qū)”(TDZ)
總結(jié):一張表格
聲明方式 | 變量提升 | 作用域 | 是否需要初始值 | 重復(fù)定義 |
---|---|---|---|---|
var | 是 | 函數(shù)級 | 不需要 | 允許 |
let | 否 | 塊級 | 不需要 | 不允許 |
const | 否 | 塊級 | 需要 | 不允許 |
擴(kuò)展:再提一下變量命名,不管是var、let、const聲明的變量名,可以由數(shù)字,字母,下劃線及美元符號組成,但是不能以數(shù)字開頭。美元符號可以放到任何一個位置,甚至多帶帶一個美元符號。
4、 循環(huán)中的塊作用域綁定循環(huán)中的let聲明
// 第一個對比 // before for(var i = 0; i < 5; i++) { // ... 省略一些代碼 } console.log(i) // 5 //after for(let i = 0; i < 5; i++) { // ... 省略一些代碼 } console.log(i) // 報錯 i is not defined // 第二個對比 // before var funcs = []; for(var i = 0; i < 10; i++) { funcs.push(() => {console.log(i)}) } funcs.forEach((ele) => { ele() }) // 打印 10次 10 // after var funcs = []; for(let i = 0; i < 10; i++) { funcs.push(() => {console.log(i)}) } funcs.forEach((ele) => { ele() }) // 打印 0 1 2 3 4 5 6 7 8 9
注意:有一點(diǎn)很重要,let 聲明在循環(huán)內(nèi)部的行為是標(biāo)準(zhǔn)中專門定義的,它不一定與 let 不提升特性有關(guān)。
循環(huán)中的const聲明
// for 循環(huán)會報錯 for (const i = 0; i < 1; i++) { console.log(i) } // 打印 0 ,然后報錯 Assignment to constant variable. // for-in 和 for-of 不會報錯 var object = { a: true, b: true, c: true }; for (const key in object) { // 不要在循環(huán)體內(nèi)更改key的值,會報錯 console.log(key) } // 打印 a b c
注意:const可以應(yīng)用在 for-in 和 for-of 循環(huán)中,是因?yàn)槊看蔚粫薷囊延薪壎ǎ菚?chuàng)建一個新綁定。
5、 塊級綁定最佳實(shí)踐的進(jìn)化ES6 早期
普遍認(rèn)為默認(rèn)使用let來替代var,對于寫保護(hù)的變量使用const
ES6 使用中
普遍默認(rèn)使用const,只有確實(shí)需要改變變量的值時使用let。因?yàn)榇蟛糠肿兞康闹翟诔跏蓟蟛粦?yīng)再改變,而預(yù)料之外的變量值的改變是許多bug的源頭。這樣就可以在某種程度上實(shí)現(xiàn)代碼的不可變,從而防止某些錯誤的發(fā)生。
6、 全局變量將逐步與頂層對象的屬性脫鉤頂層對象,在瀏覽器環(huán)境指的是window對象,在Node指的是global對象。
為了保持兼容性,var命令和function命令聲明的全局變量,依舊是頂層對象的屬性;
var a = 1; window.a // 1
另一方面規(guī)定,let命令、const命令、class命令聲明的全局變量,不屬于頂層對象的屬性。
上圖可見let 聲明的變量,并沒有在Window對象里,而是一個新的Script對象。
擴(kuò)展:如果需要在瀏覽器中跨frame或window訪問代碼,仍然可以用var在全局對象下定義變量。
7、 塊級函數(shù)從ECMAScript 6開始,在嚴(yán)格模式下,塊里的函數(shù)作用域?yàn)檫@個塊。ECMAScript 6之前不建議塊級函數(shù)在嚴(yán)格模式下使用。
"use strict"; function f() { return 1; } { function f() { return 2; } } f() === 1; // true // f() === 2 在非嚴(yán)格模式下相等
注意:在非嚴(yán)格模式下不要用塊級函數(shù),因?yàn)樵诜菄?yán)格模式下,塊中函數(shù)的聲明表現(xiàn)奇怪,有兼容性風(fēng)險
if (shouldDefineZero) { function zero() { // DANGER: 兼容性風(fēng)險 console.log("This is zero."); } }
ECMAScript 6中,如果shouldDefineZero是false,則永遠(yuǎn)不會定義zero,因?yàn)檫@個塊不執(zhí)行。這是新標(biāo)準(zhǔn)定義的。然而,這里存在歷史遺留問題,無論這個塊是否執(zhí)行,一些瀏覽器會定義zero。
在嚴(yán)格模式下,所有支持ECMAScript 6的瀏覽器以相同的方式處理:只有在shouldDefineZero為true的情況下定義zero,并且作用域只是這個塊內(nèi)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/97515.html
摘要:外層作用域不報錯正常輸出塊級作用域與函數(shù)聲明規(guī)定,函數(shù)只能在頂層作用域和函數(shù)作用域之中聲明,不能在塊級作用域聲明。規(guī)定,塊級作用域之中,函數(shù)聲明語句的行為類似于,在塊級作用域之外不可引用。同時,函數(shù)聲明還會提升到所在的塊級作用域的頭部。 前言:最近開始看阮一峰老師的《ECMAScript 6 入門》(以下簡稱原...
摘要:聲明之函數(shù)作用域和全局作用域。塊級作用域不能重復(fù)聲明臨時性死區(qū)等特性用來解決變量存在的種種問題。塊級作用域終于在外面訪問不到了。一些常量聲明使用聲明的變量名全部大寫。 ES5之前javascript語言只有函數(shù)作用域和全局作用域,使用var來聲明變量,var聲明的變量還存在變量提升使人困惑不已。我們先來復(fù)習(xí)一下ES5的var聲明,再對比學(xué)習(xí)let和const 。 var var聲明之函...
一、塊級作用域 1. var 首先看看ES5中得變量聲明方式 if (true) { var a = 2 } console.log(a) // 2 以上代碼等同于 var a if (true) { a = 2 } console.log(a) 以上可知 : 在塊內(nèi)部定義變量 變量提升,到函數(shù)最頂部 通過var聲明的變量,無論在何處聲明,均為全局作用域 2.let 和 ...
摘要:要理解閉包,首先必須理解特殊的變量作用域。使用閉包有一個優(yōu)點(diǎn),也是它的缺點(diǎn)就是可以把局部變量駐留在內(nèi)存中,可以避免使用全局變量。 js閉包 閉包是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù),創(chuàng)建閉包的常見的方式,就是在一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù),通過另一個函數(shù)訪問這個函數(shù)的局部變量。要理解閉包,首先必須理解Javascript特殊的變量作用域。變量的作用域無非就是兩種:全局變量和局部變量...
閱讀 1317·2021-10-27 14:14
閱讀 3574·2021-09-29 09:34
閱讀 2477·2019-08-30 15:44
閱讀 1715·2019-08-29 17:13
閱讀 2569·2019-08-29 13:07
閱讀 867·2019-08-26 18:26
閱讀 3342·2019-08-26 13:44
閱讀 3210·2019-08-26 13:37