1

let和const

标签(空格分隔): es6


let命令

这个命令是用来申明变量的,但是和es5不同的是,用它来声明的变量是局部变量,存在于局部作用域(blocked scope):

    var a = 1;
    console.log(this.a);   ===>  1
    
    let a = 1;(局部变量,不会挂载在window或global下)
    console.log(this.a);   ===>  undefined

此外,在写es5的时候经常会遇到变量提升的情况,比如:

    if(true) {
        console.log(a);     ====>  undefined
        var a = 1;
    }
    
    if(true) {
        console.log(a);     ====>  报错
        let a = 1;
    }

即,如果使用let进行变量申明的话,一定要先申明再使用

const命令

声明一个immutable(不可改变)的变量,而使用let申明的变量是mutable。但是需要注意的地方是使用const申明的变量是这个变量的本身只可能有一个值,是immutable的,但是并不指着个值是immutable的。这个值还是可以改变的。例如:

    cosnt obj = {}; //使用const声明了一个immutable的变量
    obj = {}        //重新对这个变量赋值,那么就会报错了
    
    
    const obj = {};
    obj.name = 'XL';
    console.log(obj); //  {name: 'XL'}这个时候是正常的

temporal dead zone

通过letconst声明的变量都有一个temporal dead zone(TDZ):当进入这个TDZ时,如果语句没有执行到申明这个变量时,在此之前get或者set这个变量都是会报错的.但是通过var申明的变量没有TDZ

通过var申明的变量的生命循环

  • 当进入到var变量的作用域中时,便为这个变量分配了存储空间。同时这个变量立即被初始化,初始值为undefined.

  • 当语句执行到赋值语句时,这个变量改变其初始值。

通过let申明的变量的生命循环

  • 当进入let申明变量的作用域中时,为这个变量分配了存储空间。但是这个变量并未没初始化。

  • 对一个还未初始化的变量进行get/set操作将会引起ReferenceError

  • 当语句执行到赋值语句时,这个变量改变其初始值。

const声明的变量必须一开就要赋值,并且这个变量不能被赋予新的值。

    const a;
    a = 'XL';   ====> 报错

在循环中的表现: var VS let VS const

  • for

  • for-in

  • for-of

for循环当中

    const arr = [];
    for(var i = 0; i < 3; i++) {
        arr.push(() => i);
    }
    arr.map(x => x());  //[3, 3, 3]

通过使用var申明变量时,会为这个值进行一次赋值,每次循环时都会重新对这个变量进行赋值。因此最后输出时,返回的是相同的值

    const arr = [];
    for(let i = 0; i < 3; i++) {
        arr.push(() => i);
    }
    arr.map(x => x());  //[0, 1, 2]

使用let申明变量的时候。每次循环过程,都相当于在一个新的blocked scope里面声明一个变量,它们相互之间没有影响,因此最后返回的值也不相同。

for-of循环和for-in循环

    const arr = [];
    for(var i of [0, 1, 2]) {
        arr.push(() => i);
    }
    arr.map(x => x());  //[2, 2, 2]

使用var申明变量时和for循环一样。

    const arr = [];
    for(let i of [0, 1, 2]) {
        arr.push(() => i);
    }
    arr.map(x => x());  //[0, 1, 2]

使用let进行循环时和for循环一样。

使用const所达到的效果和let相同,不过通过const申明的变量是immutable的。

for-in的运行过程和三者的表现和在for-of循环过程中相似。

parameters

如果使用let去申明一个和形参名字相同的变量的时候,将会报错

    function func(arg) {
        let arg;        //static error: duplicate declaration of 'arg' 
    }

但是如果使用var去申明的话,则不会报错,其达到的效果就是重新声明一个变量覆盖的掉了形式参数。

    function func(arg) {
        var arg;
    }

Coding style: const VS let VS var

  • 如果你要定义一个immutable varity原始值Forzen Objects)时,尽量使用const

  • 如果要定义一个初始值可能会发生变化的变量时,尽量使用let

  • 在全局环境下通过var来申明的变量是可以挂载到全局对象(window/global),但是你完全可以通过直接在window/global去定义这个变量/属性

参考:

exporing es6


苹果小萝卜
5.1k 声望356 粉丝

Github: [链接]