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