ES 6 (1): let 和 const 變量聲明方式

ES 6 系列為學(xué)習(xí)阮一峰老師 ECMAScript 6 入門(mén) 的一些筆記今妄。

W3C標(biāo)準(zhǔn)文檔地址: ECMAScript 6 Specification

學(xué)習(xí)ES 6 第一個(gè)概念一般都是 letconst,兩種新的聲明變量的方式盘寡。
兩者在使用上都類(lèi)似于 var 用于聲明變量员凝。

let, const 與 var 的區(qū)別

  1. 塊級(jí)作用域
    使用 letconst 聲明的變量摇锋,只在其聲明所在代碼塊內(nèi)有效(塊級(jí)作用域)苇侵。

     if(true) {
       // 這里聲明的 hello 函數(shù)只在 if 的塊級(jí)作用域內(nèi)有效
       let hello = function() {
         alert('Hello');
       }
     }
     // 試圖調(diào)用 if 作用域內(nèi)聲明的 hello 方法油狂,錯(cuò)誤历恐。
     hello();  // ReferenceError: Can't find variable: hello
    

JavaScript 代碼中需要塊級(jí)作用域的幾個(gè)場(chǎng)景:

  • 內(nèi)層變量可能會(huì)覆蓋外層變量導(dǎo)致一些不可預(yù)知的行為
  • 計(jì)數(shù)的循環(huán)變量泄露為全局變量

塊級(jí)作用域的出現(xiàn),讓廣泛使用的 IIFE (立即執(zhí)行匿名函數(shù))不再必要专筷。

ES 6 中規(guī)定函數(shù)(通過(guò)function聲明的具有變量聲明提升的方法時(shí)可看出)本身的作用域弱贼,在其所在的塊級(jí)作用域之內(nèi)。

    function f() { console.log('I am outside!'); }
    (function () {
      if(false) {
        // 重復(fù)聲明一次函數(shù)f
        // 變量聲明提升磷蛹,但是作用域依舊在 if 的塊級(jí)作用域內(nèi)
        function f() { console.log('I am inside!'); }
      }
      // 在 IIFE 作用域內(nèi)調(diào)用 f() 
      f();
    }());
上面代碼在ES5中運(yùn)行吮旅,會(huì)得到“I am inside!”,但是在ES6中運(yùn)行味咳,會(huì)得到“I am outside!”庇勃。
  1. 變量聲明提升(Hoisting) 與 暫時(shí)性死區(qū)
    使用 letconst 聲明的變量都不存在 變量聲明提升,一個(gè)變量必須先聲明然后才能使用槽驶。

關(guān)于暫時(shí)性死區(qū):在聲明變量之前使用變量會(huì)錯(cuò)誤匪凉。

    let temp = 'global temp';  // 全局作用域下聲明的 temp 變量
    if (true) {
      // if 包含的塊級(jí)作用域中的 temp 引用,由于還沒(méi)聲明所以錯(cuò)誤捺檬。
      // 這里還涉及到變量綁定的問(wèn)題再层,
      // 在 ES 6 中如果一個(gè)塊級(jí)作用域中有存在 let 命令,
      // 它所聲明的變量就 '綁定' 在這個(gè)區(qū)域堡纬,不受外部的影響聂受。
      // 這就解釋了為什么這里的 temp 沒(méi)有引用全局的 temp = 'global temp' 
      temp = 'abc';  // ReferenceError

      // 不存在變量聲明提示,所以 temp 在該作用域類(lèi)的聲明不會(huì)像 ES 3 中一樣被放到作用域最開(kāi)始的地方聲明并賦值為 undefined 
      let temp;
    }
    // ReferenceError: Cannot access uninitialized variable.

ES 6 中規(guī)定暫時(shí)性死區(qū)和不存在變量聲明提升烤镐,主要是為了減少運(yùn)行時(shí)錯(cuò)誤蛋济,防止在變量聲明前使用這個(gè)變量,從而導(dǎo)致意料之外的行為炮叶。

暫時(shí)性死區(qū)同時(shí)意味著 typeof 不再是一個(gè)百分百安全的操作(ReferenceError 錯(cuò)誤)碗旅。

    let temp = 'global temp';
    if(true){
      // 使用 typeof 操作符作用在 temp 上渡处,由于 if 作用域內(nèi)的 temp 變量目前處在 暫時(shí)性死區(qū)中,所以引用錯(cuò)誤
      console.log(typeof temp);  
      // ReferenceError: Cannot access uninitialized variable.
      let temp = 'temp';
    }
  1. 不能重復(fù)聲明
    使用 letconst 聲明的變量在同一作用域內(nèi)不能重復(fù)聲明祟辟。
    使用 var 聲明的變量如果變量名相同后聲明的變量將會(huì)覆蓋變量原來(lái)的值医瘫。

  2. 全局變量以及全局對(duì)象屬性
    ES 5 中全局對(duì)象的屬性 與 全局變量基本是等價(jià)的(也有區(qū)別,比如通過(guò) var 聲明的全局變量不能使用 delete 從 global (window/global) 上刪除旧困,在變量的訪問(wèn)上基本等價(jià))醇份。

很容易的在不知不覺(jué)中創(chuàng)建了全局變量(全局對(duì)象的屬性)

ES 6 中做了嚴(yán)格的區(qū)分,使用 var 和 function 聲明的全局變量依舊作為 全局對(duì)象的屬性吼具,使用 let, const 命令聲明的全局變量不屬于全局對(duì)象的屬性僚纷。

    let let_test = 'test';
    window.let_test;   // undefined

    var var_test = 'test';
    window.var_test;  // test

const 的一些注意事項(xiàng)

使用 let 聲明變量除了以上和 var 不同的地方,其他使用和 var 基本一致拗盒,聲明的變量可以進(jìn)行修改怖竭。

而使用 const 聲明的變量是用來(lái)聲明一個(gè)常量,一旦聲明陡蝇,常量的值是不能改變的侵状。使用時(shí)需要注意以下幾點(diǎn):

  • 一旦聲明不能修改
    嚴(yán)格模式下對(duì)已經(jīng)初始化的常量賦值會(huì)報(bào)錯(cuò)。
    非嚴(yán)格模式下對(duì)已經(jīng)初始化的常量賦值不報(bào)錯(cuò)但是無(wú)效毅整。

  • 避免只聲明不賦值
    嚴(yán)格模式下對(duì)常量聲明的變量只聲明不賦值會(huì)報(bào)錯(cuò)趣兄。
    if(true) {
    'use strict';
    const test;
    // SyntaxError: Unexpected token ';'. const declared variable 'test' must have an initializer.
    }
    非嚴(yán)格模式下不會(huì)報(bào)錯(cuò),但值是 undefined 且無(wú)法修改

  • 復(fù)合類(lèi)型 const 變量保存的是引用
    復(fù)合類(lèi)型的常量不指向數(shù)據(jù)悼嫉,而是指向數(shù)據(jù)(heap)所在的地址(stack)艇潭,所以通過(guò) const 聲明的復(fù)合類(lèi)型只能保證其 地址引用不變,但不能保證其數(shù)據(jù)不變戏蔑。

    const arr= [1, 2];
    // 修改數(shù)據(jù)而不修改引用地址蹋凝,正確執(zhí)行
    arr.push(3);  // [1, 2, 3]
    
    // 修改 arr 常量所保存的地址的值,報(bào)錯(cuò)
    arr = [];     // TypeError: Attempted to assign to readonly property.
    
  • 對(duì)象的凍結(jié)
    因?yàn)?復(fù)合類(lèi)型 const 是保存引用的原因所以存在 對(duì)象的凍結(jié)的問(wèn)題总棵。
    簡(jiǎn)單的使用 const 無(wú)法完成對(duì)象的凍結(jié)鳍寂。
    可以通過(guò) Object.freeze() 方法實(shí)現(xiàn)對(duì)對(duì)象的凍結(jié)。
    使用 Object.freeze() 方法返回的對(duì)象將不能對(duì)其屬性進(jìn)行配置(definedProperty()不可用)同時(shí)不能添加新的屬性和移除(remove)已有屬性情龄。

    In essence the object is made effectively immutable.
    本質(zhì)上是產(chǎn)生一個(gè)有效的不可變對(duì)象迄汛。

    因此對(duì)其進(jìn)行的修改將不會(huì)生效。但同樣有引用 和 數(shù)據(jù)的問(wèn)題(和復(fù)合類(lèi)型 const 變量保存的是引用一樣)骤视,所以徹底凍結(jié)對(duì)象時(shí)需要遞歸的對(duì)它的對(duì)象屬性進(jìn)行凍結(jié)鞍爱。

ES5只有兩種聲明變量的方法:var 命令和 function 命令。ES6除了添加 letconst 命令专酗,以及import 命令和 class 命令(后面將會(huì)學(xué)習(xí))睹逃。所以,ES6一共有6種聲明變量的方法祷肯。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末沉填,一起剝皮案震驚了整個(gè)濱河市疗隶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌翼闹,老刑警劉巖斑鼻,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異橄碾,居然都是意外死亡卵沉,警方通過(guò)查閱死者的電腦和手機(jī)颠锉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)法牲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人琼掠,你說(shuō)我怎么就攤上這事拒垃。” “怎么了瓷蛙?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵悼瓮,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我艰猬,道長(zhǎng)横堡,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任冠桃,我火速辦了婚禮命贴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘食听。我一直安慰自己胸蛛,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布樱报。 她就那樣靜靜地躺著葬项,像睡著了一般。 火紅的嫁衣襯著肌膚如雪迹蛤。 梳的紋絲不亂的頭發(fā)上民珍,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音盗飒,去河邊找鬼穷缤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛箩兽,可吹牛的內(nèi)容都是我干的津肛。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼汗贫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼身坐!你這毒婦竟也來(lái)了秸脱?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤部蛇,失蹤者是張志新(化名)和其女友劉穎摊唇,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體涯鲁,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡巷查,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抹腿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片岛请。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖警绩,靈堂內(nèi)的尸體忽然破棺而出崇败,到底是詐尸還是另有隱情,我是刑警寧澤肩祥,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布后室,位于F島的核電站,受9級(jí)特大地震影響混狠,放射性物質(zhì)發(fā)生泄漏岸霹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一将饺、第九天 我趴在偏房一處隱蔽的房頂上張望贡避。 院中可真熱鬧,春花似錦俯逾、人聲如沸贸桶。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)皇筛。三九已至,卻和暖如春坠七,著一層夾襖步出監(jiān)牢的瞬間水醋,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工彪置, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拄踪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓拳魁,卻偏偏與公主長(zhǎng)得像惶桐,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

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