ES6淺談(一)—— let 與 const

前言

ES6 (ECMAScript 6.0的簡(jiǎn)稱)僵朗,于2015年6月正式發(fā)布壤蚜,正式名稱是《ECMAScript 2015標(biāo)準(zhǔn)》(簡(jiǎn)稱ES2015)转绷。所以提到ES6的地方悼瓮,泛指的就是ES2015標(biāo)準(zhǔn)。

定義

let 和 const 是ES6新增加的兩個(gè)關(guān)鍵字艰猬。
let 聲明的變量只在 let 命令所在的代碼塊內(nèi)有效横堡。
const 聲明一個(gè)只讀的常量,一旦聲明冠桃,常量的值就不能改變命贴。
注:這里提到了另一個(gè)定義 代碼塊(塊級(jí)作用域 Block Scope),這也是ES6另一個(gè)重要的知識(shí)點(diǎn)食听,隨后我會(huì)整理一下塊級(jí)作用域的相關(guān)知識(shí)點(diǎn)胸蛛,再分享出來。

let 命令

let 在代碼塊內(nèi)有效
var a = 0
let b = 1
console.log(a) //輸出 0
console.log(b) //輸出 1

看起來沒什么區(qū)別樱报,但是在代碼塊內(nèi)葬项。

{
    var a = 0
    let b = 1
    console.log(a) // 輸出 0
    console.log(b) // 輸出 1
}
console.log(a) // 輸出 0
console.log(b) // 報(bào)錯(cuò) b is not defined
let 不能重復(fù)聲明

var 可以重復(fù)聲明一個(gè)變量 后聲明的變量會(huì)覆蓋之前的變量

var a = 0
var a = 1 

而let則不能在同一作用域聲明相同的變量

let a = 0
let a = 1 //報(bào)錯(cuò) Identifier 'a' has already been declared

但let可以在不同作用域聲明同名稱的變量,但值不會(huì)受到影響,而var重復(fù)聲明則會(huì)被覆蓋

var a = 0
let b = 0
{
    var a = 1
    let b = 2
    console.log(a)  //輸出1
    console.log(b)  //輸出2
}
console.log(a) //輸出1 此時(shí) a 已經(jīng)被塊內(nèi)var a = 1 覆蓋
console.log(b) //輸出0 塊內(nèi)的let b = 2 在代碼塊執(zhí)行結(jié)束后被銷毀 不影響最初定義的 let  b = 0
let 不存在變量提升
console.log(a) //輸入undefined
var a = 1

上面的代碼相當(dāng)于

var a
console.log(a) //輸入undefined
a = 1

var 定義變量是存在變量提升的
但let則會(huì)嚴(yán)格按照代碼順序執(zhí)行

console.log(a) // 報(bào)錯(cuò) a is not defined
let a = 1
暫時(shí)性死區(qū)

這個(gè)概念跟上面的變量提升有點(diǎn)類似迹蛤,但也有些許的不同民珍,舉個(gè)例子

var a = 0
{
    console.log(a) // 報(bào)錯(cuò) a is not defined
    let a = 1
}

雖然定義了全局變量,但在代碼塊內(nèi)部依舊報(bào)錯(cuò)盗飒。原因就是:

ES6明確規(guī)定了代碼塊內(nèi)如果存在let或const嚷量,代碼塊會(huì)對(duì)這些命令(let 或 const)聲明的變量從塊的開始就形成一個(gè)封閉的作用域。

所以代碼塊內(nèi)逆趣,在聲明變量a 之前使用它就會(huì)報(bào)錯(cuò)

其他

在 for 循環(huán)中 let的作用域清晰蝶溶,相對(duì)var 省去了很多煩惱

for (var i = 0; i < 10; i++) {
  setTimeout(function(){
    console.log(i);
  })
}
// 輸出十個(gè) 10
for (let j = 0; j < 10; j++) {
  setTimeout(function(){
    console.log(j);
  })
}
// 輸出 0123456789

變量 i 是用 var 聲明的,在全局范圍內(nèi)有效宣渗,所以全局中只有一個(gè)變量 i, 每次循環(huán)時(shí)抖所,setTimeout 定時(shí)器里面的 i 指的是全局變量 i ,而循環(huán)里的十個(gè) setTimeout 是在循環(huán)結(jié)束后才執(zhí)行落包,所以此時(shí)的 i 都是 10。

變量 j 是用 let 聲明的摊唇,當(dāng)前的 i 只在本輪循環(huán)中有效咐蝇,每次循環(huán)的 j 其實(shí)都是一個(gè)新的變量,所以 setTimeout 定時(shí)器里面的 j 其實(shí)是不同的變量巷查,即最后輸出0123...有序。(若每次循環(huán)的變量 j 都是重新聲明的,如何知道前一個(gè)循環(huán)的值岛请?這是因?yàn)?JavaScript 引擎內(nèi)部會(huì)記住前一個(gè)循環(huán)的值)旭寿。

const 命令

const 聲明的是一個(gè)只讀變量或常量,聲明之后不允許改變崇败。這就表示盅称,一旦聲明必須初始化肩祥,否則會(huì)報(bào)錯(cuò)。

const a = 0 // 必須初始化
const b //未初始化報(bào)錯(cuò)  Uncaught SyntaxError: Missing initializer in const declaration

對(duì)于 作用域缩膝,變量提升混狠,暫時(shí)性死區(qū)重復(fù)聲明等定義疾层,const與let是相同的

但是
對(duì)于const定義數(shù)組和對(duì)象的情況要特殊理解将饺。
這里就要理解 傳值傳址 兩種賦值方式,
簡(jiǎn)單理解:
簡(jiǎn)單類型(數(shù)值number , 字符串string , 布爾類型boolean)賦值是傳值方式
復(fù)雜類型(對(duì)象object痛黎,數(shù)組array予弧,函數(shù)function)賦值是傳址方式

var a = 0
const b = a
let c = a
a = 1
console.log(b) // 輸出 0
console.log(c) // 輸出 0

上面 const b = a 的時(shí)候是將 0這個(gè)值傳給b,所以當(dāng)a變化的時(shí)候湖饱,b不發(fā)生變化掖蛤。這里加了一個(gè) c 的目的是為了證明 b 不變因?yàn)閭髦捣绞剑皇且驗(yàn)閏onst 定義的常量琉历。

繼續(xù)看

var obj = {
    a: 1,
    b: 2
}
const obj1 = obj //這里傳遞的是 {a:1,b:2} 的地址
obj.a = 3
obj1.b = 4
console.log(obj1) // 輸出 {a: 3, b: 4}

obj = {
    c: 1,
    d: 2
}
//obj1 = obj // 這里會(huì)報(bào)錯(cuò) Uncaught TypeError: Assignment to constant variable.
console.log(obj) // 輸出 {c: 1, d: 2}
console.log(obj1) // 輸出 {a: 3, b: 4}

所以const保證指針是固定的坠七,至于指針指向的數(shù)據(jù)結(jié)構(gòu)是否發(fā)生變化就無法控制了。
這部分會(huì)有點(diǎn)繞旗笔,需要花時(shí)間理解一下彪置。

總結(jié)

  • let 和 const 的作用域?yàn)楫?dāng)前代碼塊
  • let 和 const 不能重復(fù)聲明
  • ES6 暫時(shí)性死區(qū)的概念
  • const 聲明常量,且聲明時(shí)必須初始化
  • const 聲明復(fù)雜類型是需要謹(jǐn)慎使用
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蝇恶,一起剝皮案震驚了整個(gè)濱河市拳魁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌撮弧,老刑警劉巖潘懊,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異贿衍,居然都是意外死亡授舟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門贸辈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來释树,“玉大人,你說我怎么就攤上這事擎淤∩萆叮” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵嘴拢,是天一觀的道長(zhǎng)桩盲。 經(jīng)常有香客問我,道長(zhǎng)席吴,這世上最難降的妖魔是什么赌结? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任捞蛋,我火速辦了婚禮,結(jié)果婚禮上姑曙,老公的妹妹穿的比我還像新娘襟交。我一直安慰自己,他們只是感情好伤靠,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布捣域。 她就那樣靜靜地躺著,像睡著了一般宴合。 火紅的嫁衣襯著肌膚如雪焕梅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天卦洽,我揣著相機(jī)與錄音贞言,去河邊找鬼。 笑死阀蒂,一個(gè)胖子當(dāng)著我的面吹牛该窗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蚤霞,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼酗失,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了昧绣?” 一聲冷哼從身側(cè)響起规肴,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎夜畴,沒想到半個(gè)月后拖刃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贪绘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年兑牡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片税灌。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡均函,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出垄琐,到底是詐尸還是另有隱情边酒,我是刑警寧澤经柴,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布狸窘,位于F島的核電站,受9級(jí)特大地震影響坯认,放射性物質(zhì)發(fā)生泄漏翻擒。R本人自食惡果不足惜氓涣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望陋气。 院中可真熱鬧劳吠,春花似錦、人聲如沸巩趁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽议慰。三九已至蠢古,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間别凹,已是汗流浹背草讶。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留炉菲,地道東北人堕战。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像拍霜,于是被迫代替她去往敵國和親嘱丢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容