1. 程式人生 > >JavaScript var、let、const

JavaScript var、let、const

全局 變量提升 enc ant 特性 數組 reference efi 範圍

1. 概述

1.1 說明

在ES5 聲明變量的方法:var命令和function命令。

在ES6 聲明變量的方法:var命令、function命令、let命令、const命令、import命令、class命令。

以下內容主要是對 let 、var 、const 命令的理解與記錄。

1.2 let 命令

1.2.1 let 說明

  let命令的聲明變量用法類似於var,如 let a =10;(聲明了一個變量:變量名為a,值為10)。但let所聲明的變量,只在let命令所在的代碼塊內有效,即let用於聲明一個塊級作用域的變量。

  以下代碼解析:在函數test中的if代碼塊中使用let進行聲明變量;在if代碼快中調用所聲明變量可以獲取正確的值,而在if代碼塊外調用所聲明變量則會報錯。

    function test() {
        if (true) {
            let x = 1;
            console.log(x); // 1
        }
        console.log(x); // Uncaught ReferenceError: x is not defined
    }
    test();

  for循環的計數器

    for (let x = 0; x < 5; x++) {
        setTimeout(function() {
            console.log(x); 
// 0 1 2 3 4 }, 100); } console.log(x);// Uncaught ReferenceError: x is not defined

1.2.1 let 特性

  詳見 var 與 let 的對比。

  • 塊級作用域
  • 不允許在相同作用域內,重復聲明同一個變量
  • 暫時性死區

1.3 var 命令

1.3.1 var 說明

  使用var進行聲明變量。var a =10;(聲明了一個變量:變量名為a,值為10)。在ES6之前,JavaScript沒有塊級作用域,只有全局作用域和函數作用域。變量提升即是將變量聲明提升到它所在作用域的最開始的部分。

   //全局作用域
    console.log(global); // undefined
    var global = ‘global‘;
    console.log(global); // global
    //函數作用域
    function test () {
        console.log(x); // undefined
        var x = 1;
        console.log(x); // 1
    }
    test();// 調用函數

  以上代碼中var聲明的變量在不同作用域中進行了變量提升(在當前作用域下,在聲明變量之前進行了調用,返回了變量值為undefined)。以上代碼等同於以下代碼:

    var global; // 變量提升,全局作用域範圍內,此時只是聲明,並沒有賦值
    console.log(global); // undefined
    global = ‘global‘; // 此時才賦值
    console.log(global); // global

    function test () {
        var x; // 變量提升,函數作用域範圍內
        console.log(x);// undefined
        x = 1;// 此時才賦值
        console.log(x);// 1
    }
    test();

  for循環的計數器

    for (var x = 0; x < 5; x++) {
        console.log(x); // 0 1 2 3 4
        setTimeout(function() {
            console.log(x); // 5 5 5 5 5
        }, 100);
    }
    console.log("***************");
    console.log(x);// 5

1.3.2 省略 var

 在javascript中,若省略var關鍵字而直接賦值,那麽這個變量為全局變量,哪怕是在function裏定義的。

    function a() {
        x = 2;
    }
    function b() {
        console.log(x);// 2
    }
    a();
    b();

1.4 let 與 var

  • 作用域的區別

    var : 沒有塊級作用域,因為變量提升的特性,其聲明變量的作用域為整個函數或全局範圍。

    let : 擁有塊級作用域的特性,其聲明的變量作用域範圍從聲明處一直到當前塊級語句({}包含)的結尾【或一直延伸到函數結尾(在函數內)或全局結尾】。

    function testVar() {
        if (true) {
            // 變量提升
            console.log(x); //  undefined
            var x = 1;
            console.log(x); // 1
        }
        // 作用域在整個函數作用域中
        console.log(x); // 1
    }
    function testLet() {
        if (true) {
            // 不存在變量提升
            console.log(y); //  Uncaught ReferenceError: y is not defined
            let y = 1;
            console.log(y); // 1
        }
        // 作用域僅在if語句塊中
        console.log(y); // Uncaught ReferenceError: y is not defined
    }
    testVar();
    testLet();
  • 重復聲明

    var : 允許在相同作用域內,重復聲明同一個變量。

    let : 不允許在相同作用域內,重復聲明同一個變量。

    function test() {
        var x=1;
        var x=2;
        var x=3;
        console.log(x);//3
        let y=1;
        let y=2;
        console.log(y);//Uncaught SyntaxError: Identifier ‘y‘ has already been declared
    }
    test();
  • 頂層對象的屬性(window)

    var : 在全局作用域聲明的變量,會作為widnow對象的成員。

    let : 在全局作用域聲明的變量,不會作為window對象的成員。

    var x = 1;
    let y = 1;
    //var聲明的變量附加到window對象上
    console.log(window.x); // 1
    //let聲明的變量沒有附加到window對象上
    console.log(window.y); // undefined
  • 暫時性死區

    var : 不存在暫時性死區。

    let : 存在暫時性死區【在代碼塊內,使用let命令聲明變量之前,該變量都是不可用的。這在語法上,稱為“暫時性死區”(temporal dead zone,簡稱 TDZ)】。

    var a = 123;
    if (true) {
        a = ‘abc‘;
        console.log(a);// abc
        var a;
        console.log(a);// abc
    }
    var x = 123;
    if (true) {
        x = ‘abc‘; // Uncaught ReferenceError: x is not defined
        let x;
    }

  備註:ES6 明確規定,如果區塊中存在letconst命令,這個區塊對這些命令聲明的變量,從一開始就形成了封閉作用域。凡是在聲明之前就使用這些變量,就會報錯

1.5 const 命令

1.5.1 const 說明

  使用const進行聲明變量所定義的是一個只讀的常量,一旦聲明,常量的值就不能改變。const a =10;(聲明了一個常量變量:變量名為a,值為10)。

    const x = 1;
    x = 2; // Uncaught TypeError: Assignment to constant variable

1.5.2 const 特性

  • 塊級作用域(與let命令相同)
  • 不允許在相同作用域內,重復聲明同一個變量(與let命令相同)
  • 暫時性死區(與let命令相同)
  • 在全局作用域聲明的變量,不會作為window對象的成員
  • 當用const聲明的常量為值類型(e.g. String、Number)時,修改此常量的值會報錯;但當聲明的常量為引用類型(e.g. Array、Object)時,只可以修改此常量的成員
    // 1.const聲明一個數組
    const x = [1, 2, 3];
    console.log(x); // => [1, 2, 3]
    x[0] = "a"; // 修改數組的第一個元素的值
    console.log(x); // [‘a‘, 2, 3]

    // 2.const聲明一個對象
    const obj = {};
    obj.name = ‘objName‘;
    console.log(obj.name); // objName

JavaScript var、let、const