Es6 Block Binding

es5es6的區(qū)別里,關(guān)于塊級(jí)綁定是被津津樂道的。之前沒有記錄,今天就把它記錄下來(lái)。
我們知道var會(huì)有變量提升。
es6letconst可以避免這個(gè),且會(huì)生成塊級(jí)作用域。

塊級(jí)聲明

  1. function里面
  2. 塊內(nèi)(由{}字符表示)
let 聲明
function getValue(condition) {

    if (condition) {
        let value = "blue";

        // other code

        return value;
    } else {

        // value 不存在這里

        return null;
    }

    // value 不存在這里
}
無(wú)重復(fù)聲明
var count = 30;

// Syntax error
let count = 40;

上面會(huì)報(bào)錯(cuò),count被聲明兩次:一次使用var,一次使用let。因?yàn)?code>let不會(huì)重新定義已存在于同一范圍內(nèi)的標(biāo)識(shí)符,所以let聲明將引發(fā)錯(cuò)誤。

var count = 30;

// Does not throw an error
if (condition) {

    let count = 40;

    // more code
}

這個(gè)不會(huì)報(bào)錯(cuò),因?yàn)閷?shí)在新的作用域(塊級(jí))創(chuàng)建的新變量。

The Temporal Dead Zone

if (condition) {
    console.log(typeof value);  // ReferenceError!
    let value = "blue";
}

這個(gè)就是所謂的tdz,TDZ永遠(yuǎn)不會(huì)在ECMAScript規(guī)范中明確命名,但該術(shù)語(yǔ)通常用于描述為什么letconst聲明在聲明之前無(wú)法訪問(wèn)。

當(dāng)js引擎查看即將發(fā)生的塊并找到變量聲明時(shí),它會(huì)將聲明提升到函數(shù)頂部或全局范圍(對(duì)于var),或者將聲明放在TDZ中(對(duì)于letconst)。

上面的例子會(huì)報(bào)錯(cuò),因?yàn)樵谶@個(gè)塊級(jí)作用域內(nèi)的聲明之前存在這個(gè)TDZ,但是你可以在塊級(jí)作用域外使用:

console.log(typeof value);     // "undefined"

if (condition) {
    let value = "blue";
}

TDZ只是塊綁定的一個(gè)獨(dú)特方面。另一個(gè)獨(dú)特的方面與它們?cè)谘h(huán)內(nèi)的使用有關(guān)。

block binding in loops

var funcs = [];

for (var i = 0; i < 10; i++) {
    funcs.push(function() { console.log(i); });
}

funcs.forEach(function(func) {
    func();     // 輸出 "10" 十次。
});

es6之前解決這個(gè)問(wèn)題可以使用IIFE。

var funcs = [];

for (var i = 0; i < 10; i++) {
    funcs.push((function(value) {
        return function() {
            console.log(value);
        }
    }(i)));
}

funcs.forEach(function(func) {
    func();     // 0,1,2,...
});

但是es6之后,可以直接使用let。

var funcs = [];

for (let i = 0; i < 10; i++) {
    funcs.push(function() {
        console.log(i);
    });
}

funcs.forEach(function(func) {
    func();     // outputs 0, then 1, then 2, up to 9
})

這個(gè)是因?yàn)樵诿看蔚牡?,都?huì)創(chuàng)建一個(gè)新的變量,這就導(dǎo)致每個(gè)創(chuàng)建的內(nèi)部的方法都有一個(gè)自己的變量。每次創(chuàng)建的時(shí)候,都會(huì)分配值。

重要的是要理解循環(huán)中l(wèi)et聲明的行為是規(guī)范中特別定義的行為,并不一定與let的非提升特性有關(guān)。實(shí)際上,let的早期實(shí)現(xiàn)沒有這種行為,因?yàn)樗院笤谶^(guò)程中添加。

const 和 let

其實(shí)const的行為和let的行為差不多。只是const定義的是常量,不變的數(shù)據(jù)。let定義的是改變的數(shù)據(jù)。并且在聲明const的時(shí)候必須存在值。

const name; //error
const name = 'my name' 
name = 'your name' // error
let age;
age = 18;

對(duì)于const需要明確一點(diǎn),就是改變的是什么?看下面這個(gè)。

const person = {
    name: "Nicholas"
};

// works
person.name = "Greg";

// throws an error
person = {
    name: "Greg"
};

可以更改person.name而不會(huì)導(dǎo)致錯(cuò)誤,因?yàn)檫@會(huì)更改person包含的內(nèi)容,并且不會(huì)更改person綁定的值。當(dāng)此代碼嘗試為person分配值(從而嘗試更改綁定)時(shí),將引發(fā)錯(cuò)誤。const如何與對(duì)象一起工作的這種微妙之處很容易被誤解。請(qǐng)記?。?strong>const阻止修改綁定,而不是阻止修改綁定值。

本文出自

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • let 和 const 命令 let 命令 塊級(jí)作用域 const 命令 頂層對(duì)象的屬性 gl...
    安小明閱讀 1,047評(píng)論 0 0
  • 第一章:塊級(jí)作用域綁定 塊級(jí)聲明 1.var聲明及變量提升機(jī)制:在函數(shù)作用域或者全局作用域中通過(guò)關(guān)鍵字var聲明的...
    BeADre_wang閱讀 1,009評(píng)論 0 0
  • ? 何為ES6語(yǔ)法糖?即這些事情ES5也可以做,只是稍微復(fù)雜一些,而ES6提供了非破壞性的更新, 目的是提供更簡(jiǎn)潔...
    果汁涼茶丶閱讀 1,400評(píng)論 0 4
  • 微商在發(fā)展到今天的境界,自己怎么做微商?當(dāng)然也很多成功的微商,但為什么很多微商還沒有好好發(fā)育就被淘汰了,很...
    ec6e3dd8d44b閱讀 430評(píng)論 0 0
  • 我叫陳奕君,現(xiàn)在是三年級(jí)的學(xué)生。性格開朗大方,平時(shí)不愛說(shuō)話但很愛運(yùn)動(dòng),是學(xué)校田徑隊(duì)的隊(duì)長(zhǎng)。 我有...
    王者榮耀大神閱讀 268評(píng)論 1 0

友情鏈接更多精彩內(nèi)容