深切明白ES6 - var-let-const

知識點

var 聲明變量:
1、存在變量提拔,實際上var不管在那裡聲明,都邑被當作當前的作用域頂部聲明變量。
2、能夠反覆聲明,后聲明的變量會掩蓋前聲明的變量。
let 聲明變量:
1、不存在變量提拔。
2、制止反覆聲明。
3、塊級作用域,只在當前作用域塊有用。
4、暫時死區,而且不能在聲明之前接見它。
const聲明常量:
1、const 聲明的是常量,其值一旦肯定后不能夠修正
2、const 聲明常量時刻必需要舉行賦值
3、const 不存在變量提拔,一旦實行快外就會馬上燒毀。
4、const 只能在當前代碼塊級有用,
5、const 不能反覆聲明雷同常量。
6、const聲明不許可修正綁定,但許可修正值,也就是說用const建立對象后,能夠修正該對象的屬性值。

一、聲明JavaScript的變量有哪些?

每種編程言語都有變量,聲明變量的要領各不同,在JavaScript內里,最典範的var聲明一個變量,當ECMAScript6湧現后,新增了2個聲明變量的要領:let和const,那什麼時候建立變量,用什麼聲明變量要領會更好呢?

二、先談談var聲明及變量提醒(hoisting)機制

var聲明一個變量時刻,只需要 var name; 或許聲明賦值var name = “Bob”;

實際上var不管在那裡聲明,都邑被當作當前的作用域頂部聲明變量。

(1)什麼是變量提醒機制?
// var 的變量提拔機制
function getValue(condition) {
    if (condition) {
        var values = 'Bob';
        return values;

    } else {
        console.log(values); // 這裏接見到values 是undefined,緣由下面詮釋:
        return null;
        
    }
}


// 緣由詮釋:為何上面的代碼else還能接見values的值,雖然是undefined
// 不管變量values都邑被建立,在編譯歷程當中,JavaScript引擎會將上面的getValue函數修正成如許:
function getValue(condition) {

    // 重點看這裏,變量values的聲明被提拔到函數頂部
    var values;

    if (condition) {
        values = 'Bob';
        return values;

    } else {
        console.log(values); // 所以這裏接見到是聲明過的但未賦值的values,所以是undefined。
        return null;
        
    }
}

三、塊級聲明的湧現

塊級聲明用於聲明在指定的塊的作用域以外無法接見的變量

  • 函數內部
  • 塊級中(字符{ }之間的地區)

四、let聲明

let聲明變量和var聲明變量,但let有本身的四個特性:

  • 塊級作用域,限定在當前的塊級作用域中,表面作用域無法接見。
  • 不存在變量提拔。
  • 暫時死區,而且不能在聲明之前接見它。
  • 制止反覆聲明雷同的變量,不然報錯。

我們能夠把適才聊到的getValue函數修正一下:

// let 塊級作用域 && 不存在變量提拔
function getValue(condition) {
    if (condition) {

        // 運用let聲明變量
        let values = 'Bob';
        return values;

    } else {
        console.log(values); // 這裏報錯: ReferenceError: values is not defined..
        // 緣由就是用let聲明的變量,是不存在變量提拔的,
        // 而且values變量只能在if{ 這個作用塊內里有用 } 表面是接見不到的
        // 同時,在表面接見不僅會接見不到,而且會報錯

        return null;

    }
}


// let 制止反覆聲明雷同變量
function getValue() {
    var values = "Bob";
    let values = {name: 'Bob'};
    
    // 運用let聲明變量制止反覆聲明已有的變量名
    // 不然報錯:SyntaxError: Identifier 'values' has already been declared
}

五、const聲明

  • const 聲明的是常量,其值一旦肯定后不能夠修正。
  • const 聲明常量時刻必需要舉行賦值。
  • const 不存在變量提拔,一旦實行快外就會馬上燒毀。
  • const 只能在當前代碼塊級有用,
  • const 不能反覆聲明雷同常量。
  • const聲明不許可修正綁定,但許可修正值,也就是說用const建立對象后,能夠修正該對象的屬性值。
function getValue() {
    // 聲明一個常量
    const USER_NAME = "梁鳳波";

    // 制止反覆聲明雷同常量,不然報錯:TypeError: Assignment to constant variable.
    // const USER_NAME = "Bob";
    
    // 記着:const聲明不許可修正綁定,但許可修正值,
    // 也就是說用const建立對象后,能夠修正該對象的屬性值
    const STUDYENT = {
        name: '梁鳳波'
    };

    console.log(`STUDYENT.name =  ${STUDYENT.name}`); // STUDYENT.name =  梁鳳波

    STUDYENT.name = 'Bob';
    console.log(`STUDYENT.name =  ${STUDYENT.name}`); // STUDYENT.name =  Bob
}

拓展:輪迴中的塊級作用域綁定

接見for輪迴后的結果
// 在for輪迴內用var 聲明,在表面接見到的是for輪迴后的結果
for (var i = 0; i < 10; i++) {
}
console.log(`i = ${i}`); // i = 10

// 在for輪迴內用let 聲明,在表面 接見不到,塊級作用域題目
for (let i = 0; i < 10; i++) {
}
console.log(`i = ${i}`); // ReferenceError: i is not defined
輪迴中的var聲明
// 經由for輪迴后,在表面接見i,是直接接見到了結果i = 10

let funcs = [];
for (var i = 0; i < 10; i++) {
    funcs.push(function () {
        console.log(i);
    })
}

funcs.forEach(func => {
    func() // 離別輸出10次10
});

緣由:輪迴里每次迭代同時同享着變量i,輪迴內部建立的函數全保存雷同變量的援用,輪迴完畢時刻i的值變成10,所以每次挪用console.log(i)時刻回輸出数字10

為了處理這個題目,能夠在輪迴中運用馬上挪用函數表達式(IIFE),以強迫天生計數器變量的副本:

運用var到達抱負狀況
// 假如要抱負結果,在表面離別輸出 0 ~ 9,
// 能夠運用閉包暴露出去
let funcs = [];
for (var i = 0; i < 10; i++) {
    funcs.push((function (val) {
        return function () {
            console.log(val);
        }
    }(i)))
}

funcs.forEach(func => {
    func()
});
輪迴中的let聲明
let funcs = [];
for (let i = 0; i < 10; i++) {
    funcs.push(function () {
        console.log(i);
    })
}

funcs.forEach(func => {
    func() // 離別輸出 0 ~ 9
});

let 聲明模擬上述示例IIFE所做的一切簡化輪迴歷程,每次迭代輪迴都邑建立一個新變量,並以之前迭代中同名變量的值將其初始化。

輪迴中的const聲明
let funcs = [];
let obj = {
    a: true,
    b: true,
    c: true
}

for (const key in obj) {
    funcs.push(function () {
        console.log(key);
    })
}

funcs.forEach(func => {
    func() // 離別輸出 a, b, c Authorization
});

let和const聲明輪迴,const輪迴是不能轉變key的值,const 輪迴應當運用for-in,for-of,其他和let示例一樣,由於每次迭代不會像var輪迴例子一樣修正已有的綁定,而是會建立一個新綁定。

全局塊級作用域綁定

var RegExp = "Bob";

// 即使是全局對象RegExp定義在window,也不能倖免被var聲明掩蓋
console.log(RegExp); // Bob
console.log(window.RegExp); // Bob

let RegExp = "Bob";

// 用let或const聲明不能掩蓋全局變量,而只能屏障它
console.log(RegExp); // Bob
console.log(window.RegExp); // undefined
console.log(window.RegExp === RegExp); // false

const ncz = 'Hi!'
console.log('ncz' in window); // false

末了聊一聊塊級綁定的最好實踐

默許運用const,只在確切需求轉變變量的值運用let,如許就能夠在某種程度上完成代碼的不可變,從而防備默寫毛病發生。

    原文作者:梁鳳波
    原文地址: https://segmentfault.com/a/1190000015049579
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞