const & let

前世

在 const & let 還未出現前,JS 的世界一直是 var的統治

var:在JS中用於變量聲明的關鍵字。

特點:

  1. 變量提升
  2. 只有函數作用域或者全局作用域,沒有塊級作用域
  3. 重複聲明變量
  4. 循環體重的閉包會出現問題

    …….

變量提升

function test(tag) {
    console.log(a,b);   // a,b在下面聲明,但是會打印出undefined,不會報錯
    
    if(10 >= tag) {
        var a = tag + 1;
    } else {
        var b = tag - 1;
    }
}

在瀏覽器預解析機制中,加載函數的時候,此時的作用域爲函數作用域,函數作用域中JS會先將所有的聲明置頂。

function test(tag) {
    var a,b;            // 將聲明置頂,但是賦值並不會
    console.log(a,b);   // a,b在下面聲明,但是會打印出undefined,不會報錯
    
    if(10 >= tag) {
        var a = tag + 1;
    } else {
        var b = tag - 1;
    }
}

只有函數作用域以及全局作用域,沒有塊級作用域

function test(tag) {
    console.log(a,b);   // a,b在下面聲明,但是會打印出undefined,不會報錯
    
    if(10 >= tag) {
        var a = tag + 1;
    } else {
        var b = tag - 1;
    }
    
    console.log(a);        // 9
}

test(8)  // 9

按照其他語言規則 if 是一個程序塊,在 if 中聲明的變量作用域只能在 if 中,但是 JS 因爲只有函數作用域和全局作用域,所以纔會導致在 if 判斷外還可以訪問 if 的變量

重複聲明變量

var a = 1;
var a = 2;

console.log(a); // 2

在使用var的時候允許重複聲明變量也是令人頭痛的事情,也許因爲這個機制,可能就會出現bug

循環體重的閉包會出現問題

var arr = [];
for(var i = 0; i < 3; i++) {
    arr.push(function () {
        return i;
    })
}

for(var j = 0; j < 3; j++) {
    console.log(arr[j]());    // 3,3,3
}

將var -> let
將會打印出 0,1,2

因爲缺乏塊作用域所以導致問題出現

今生

如今距離ES6規範的出現已經過去了4年多了,在項目中也早已開始大量使用ES6規範編寫代碼了。var也不再是JS世界的唯一了,

JS 世界出現了const & let。

const & let 的出現給JS帶來了塊級作用域,解決了變量提升,禁止了重複聲明變量,讓JS少了很多疑惑的地方。

let & const

相同點:

  1. 具有塊級作用域
  2. 禁止重複聲明變量
  3. 不會產生變量提升

區別:

let

使用let聲明的基本類型變量是可以改變值

let a = 12;
a = 13;
return a;    // 13

使用let聲明引用類型的變量是可以改變引用的

let info = {
    name: "ming995",
    age: 25,
    sayHi: function() {
        console.log(`Hi I'm ${this.name}`)
    }
};

let heInfo = {};

heInfo = info;

heInfo.name = "Jack";

console.log(heInfo);

const

使用const聲明的基本類型變量是不可以改變值

const a = 13;
a = 14;
return a; // 報錯

使用const聲明引用類型的變量是不可以改變引用的

const info = {
    name: "ming995",
    age: 25,
    sayHi: function() {
        console.log(`Hi I'm ${this.name}`)
    }
};

const heInfo = {};

heInfo = info;        // 報錯
    
heInfo.name = "Jack";

console.log(heInfo);

但是我們可以操作const聲明的引用類型的屬性值

const info = {
    name: "ming995",
    age: 25,
    sayHi: function() {
        console.log(`Hi I'm ${this.name}`)
    }
};

info.language = "js";

console.log(info);

總結

之前對於const的理解有偏差,所以就寫這篇文章。var時代已經過去了,ES6各種特性用起來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章