ES6學(xué)習(xí)-塊級作用域綁定

var聲明及變量提升(Hoisting)機制

function getValue(){
    if(condition){
        var value="blue";
        //其他代碼
        return value;
    }else{
        //此處可訪問變量value,其值為undefined
        return null;
    }
    //此處可訪問變量value,其值為undefined
}

在函數(shù)作用域通過var聲明的變量,無論在哪里聲明都會被當(dāng)成作用域頂部聲明的變量,但是初引入塊級始化操作依然在原處執(zhí)行。對此,有些開發(fā)者不習(xí)慣則會以為是bug,為此,ECMAScript6引入塊級作用域來強化對變量聲明周期的控制。

塊級聲明

塊級作用域用于聲明 在指定塊的作用域之外無法聲明的變量。

let聲明
function getValue(){
    if(condition){
        let value="blue";
        //其他代碼
        return value;
    }else{
        //此處value不存在
        return null;
    }
    //此處value不存在
}

變量使用let聲明后,不再被提升到函數(shù)頂部,執(zhí)行流離開if塊,value立即被銷毀。

禁止重聲明
var count=30;
//拋出語法錯誤
let count=40;

同一作用域內(nèi)不能用let聲明已聲明過的變量,但是不同作用域可以聲明。

var count=30;
if(condition){
    //不會拋出錯誤
    let count=40;
    //更多代碼
}
const聲明

ECMAscript6標(biāo)準(zhǔn)還提供了const關(guān)鍵字。使用const聲明的是常量,其值一旦被設(shè)定就不可更改,使用每個常量必須初始化。

//有效的常量
const maxItems=30;
//語法錯誤;常量為初始化
const name;

這里聲明的name沒有初始化,所以會拋出語法錯誤。
const和let
const和let都是塊級標(biāo)識符,所以常量也只在當(dāng)前代碼塊有效,一旦執(zhí)行到快外就會被立即銷毀。常量同樣不會被提升到頂部。

if(condition){
    const maxItems=5;
    //更多代碼
}
//此處無法訪問maxItems

與let相似,在同一作用域用const聲明已存在的標(biāo)識符也會導(dǎo)致語法錯誤。

var message-"Hello";
let age=25;
//這兩條語句都會報錯
const message="Goodbye";
const age=30;

盡管相似之處很多,但const和let聲明有很大的一處不同,const常量不可以再賦值。

const age=25;
//這語句都會報錯
age=30;

但是如果const聲明的是對象,則對象中的值可以修改。

用const聲明對象

const不允許修改綁定,但允許修改值。

const person={
    name:"ccg"
};
//可以修改對象中屬性的值
person.name="yeshi";
//拋出語法錯誤
person={
    name:"cc"
};
臨時死區(qū)

JavaScript引擎在掃描代碼發(fā)現(xiàn)聲明時,要么將它們提升至作用域頂部(遇見var聲明),要么將聲明放到TDZ中(遇到let和const聲明時),只有執(zhí)行過變量聲明語句后,變量才會從TDZ中移出,然后才可以訪問。

console.log(typeof value);//undefined,value處于TDZ中
if(condition){
    let value="blue";//從TDZ移出
    console.log(typeof value);//srting
}

循環(huán)中的塊作用域綁定

使用let可以把計數(shù)器變量限制在循環(huán)內(nèi)部。

for (var i = 0; i <10; i++){
    process(items[i]);
}
//在這里仍然可以訪問i
console.log(i);
for (let i = 0; i <10; i++){
    process(items[i]);
}
//在這里不可以訪問i
console.log(i);
循環(huán)中的函數(shù)

let聲明每次迭代都會創(chuàng)建一個新變量,并以之前迭代的同名變量的值將其初始化。

var funcs=[];
for(let i=0;i<10;i++){
    funcs.push(function(){
        console.log(i);
    });
}
funcs.forEach(function(func){
    func();//0,1,2,3,4,5,6,7,8,9
})

對于for-in,for-of循環(huán)也一樣

var funcs=[],
    object={
        a:true,
        b:true,
        c:true
    };
for(let key in object){
    funcs.push(function(){
        console.log(key);
    });
}
funcs.forEach(function(func){
    func();//輸出a、b、c
});

let聲明在循環(huán)內(nèi)部的行為是標(biāo)準(zhǔn)中專門定義的、它不一定與let的不提升特性相關(guān),理解這一點至關(guān)重要。事實上,早期的let不包含這行為,這是后來加入的。

循環(huán)中的const聲明

對于for循環(huán)來說,可以在初始化時使用const,但是不可修改其值。

var funcs=[];
for(const i=0;i<10;i++){
    funcs.push(function(){
        console.log(i);
    });
}//拋出錯誤

對于,for-in和for-of循環(huán),使用const行為和let一致,

var funcs=[],
    object={
        a:true,
        b:true,
        c:true
    };
for(const key in object){
    funcs.push(function(){
        console.log(key);
    });
}
funcs.forEach(function(func){
    func();//輸出a、b、c
});

之所以可以運用在for-in和for-of循環(huán)中,是因為每次迭代不會修改已有綁定,而是會創(chuàng)建一個新的綁定。

全局塊作用域的綁定

let和const與var另外一個區(qū)別就是它們在全局作用域中的行為。var聲明的東西會成為讓全局對象的一個屬性,而let和const并不會。
如果你在全局作用域中使用let或者const,會在全局中創(chuàng)建一個新的綁定,但是該綁定不會添加到全局對象的屬性。

var ccg="ccg";
window.ccg;//ccg
let ccgg="ccgg";
window.ccgg;//undefined
const cgg="cgg";
window.cgg;//undefined

塊級綁定最佳實踐

默認(rèn)使用const,只有確實需要改變變量的值時才使用let,有需要再使用var。因為大部分變量的值的改變都是

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

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

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