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 Todayhtml

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

另外,函數自己的做用域也在定義他的塊的做用域內。code

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

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

hello();

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

注意事項

不能先使用,後定義

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就是外部的變量,這個時候就不會出錯。blog

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.

相關文章
相關標籤/搜索