ES6+ 現在就用系列(二):let 命令


系列目錄

ES6+ 現在就用系列(一):為什么使用ES6+
ES6+ 現在就用系列(二):let 命令
ES6+ 現在就用系列(三):const 命令
ES6+ 現在就用系列(四):箭頭函數 =>
ES6+ 現在就用系列(五):模板字面量 (Template Literals)
ES6+ 現在就用系列(六):解構賦值 (Destructuring )
ES6+ 現在就用系列(七):Promise
ES6+ 現在就用系列(八):類 (Class),繼承,對象的擴展
ES6+ 現在就用系列(九):模塊
ES6+ 現在就用系列(十):Async 異步編程
ES6+ 現在就用系列(十一):ES7 Async in Browser Today

ES6新增了let命令,用來聲明變量。它的用法類似於var,但是所聲明的變量,只在let命令所在的代碼塊內有效。也就是有了塊級作用域。

為什么需要塊級作用域?

避免 var 變量提升帶來的副作用

示例:

var saleCount = 20;

function f(){    
    console.log(saleCount);
    if(saleCount<100)
    {   
        // according some rule, change it to 100
        var saleCount=60;
        console.log(saleCount);
    }    
}

f() 

輸出: // undefined

因為 "var saleCount=60;" 作用域是整個函數,而JavaScript里var定義的變量存在變量提升,也就是console.log(saleCount), 這個saleCount是 "var saleCount=60;" 這一句定義的,當調用的時候,saleCount的值是undefined. 實際上等於下面代碼。

var saleCount = 20;

function f(){ 
    
    var saleCount;   
    console.log(saleCount);
    if(saleCount<100)
    {   
        // according some rule, change it to 100
        saleCount=60;
        console.log(saleCount);
    }

}

f() // undefined  

避免循環變量變為全局變量

示例:

    for (var i = 0; i < 10; i++){
    // do something
    }

    console.log(i);
    輸出: 10

很明顯,我們不希望i,這個變量變為全局變量。    

let 示例代碼

'use strict'
{
    var b=1;
    let a=2;
}

console.log(a);
console.log(b);

# 輸出: ReferenceError: a is not defined

上一節我們給出了如下的示例:

var a = [];
for (var i = 0; i < 10; i++) {
    a[i] = function () {
        console.log(i);
    };
}
a[1]();
a[2]();
a[3]();

輸出: 10,10,10

我們看到,輸出的結果不是我們想要的,因為i是用var定義的,那么他在全局范圍內都是生效的,也就是我們循環結束以后,i的值就是10,那么不管調用數組的那個元素,console.log(i) 輸出的都是10, 那么let因為有了塊級作用域,就可以避免這個問題。

var a = [];
for (let i = 0; i < 10; i++) {
    a[i] = function () {
        console.log(i);
    };
}
a[1]();
a[2]();
a[3]();

輸出 1, 2,3

另外,函數本身的作用域也在定義他的塊的作用域內。

function hello(){console.log("Hello, Jack")};

{
    function hello(){console.log("Hello, Tom")};
}

hello();  

上面的代碼在ES6里面輸出了"Hello, Jack", 而在ES5里輸出了"Hello, Tom".

注意事項

不能先使用,后定義

console.log(x);
console.log(y);

var x = 1;
let y = 2;

# 輸出
undefined
ReferenceError: y is not defined

上面的代碼由於x是var定義的,一開始x的變量是存在的,只是值是undefined, 但是由於y 是let定義的,就不存在變量提升。

暫時性死區

如果一個變量是使用let定義的,那么這個變量就屬於聲明時所在的代碼塊,也就是變量不再受外部影響,下面的a 由於在塊里定義了,所以 會報錯,因為在那個塊里是先使用后定義,如果去掉“let a”, 那么a就是外部的變量,這個時候就不會出錯。

var a = "hello";

{
    a = 'world'; 
    let a;
}

// ReferenceError

不能重復申明

也就是不能重復申明同一個變量,即使一個是let申明,一個是用var申明也不行。 下面的代碼都會報錯。

function () {
    let a = 10;
    var a = 1;
}


function () {
    let b = 10;
    let b = 1;
}

總結

由於let 避免了很多問題,所以建議在ES6的代碼里總是使用let 來替代var.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM