这两个语法与之前ES5声明变量的var的相同和区别

都是用来声明变量,而且是全局作用域

ES5 var 只有全局作用域 和 函数作用域,没有块级作用域

ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效

    {    
        var a = 10;
        let b = 1;
    }
    console.log(a)  
    console.log(b)

输出结果:

    [Running] node "c:\web\single\test.js"    
    10
    c:\web\single\test.js:68
    console.log(b)  
                ^
    ReferenceError: b is not defined

for循环的计数器,就很合适使用let命令。

    for (let i = 0; i < 10; i++) {    
      // ...
    }
    console.log(i);
    // ReferenceError: i is not defined

for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

    for (let i = 0; i < 3; i++) {    
        let i = 'abc';
        console.log(i);
    }
    
    // abc
    // abc
    // abc

上面代码正确运行,输出了 3 次abc。这表明函数内部的变量i与循环变量i不在同一个作用域,有各自单独的作用域。

var命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined。这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。

为了纠正这种现象,let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。

    // var 的情况    
    console.log(foo); // 输出undefined
    var foo = 2;
    // let 的情况
    console.log(bar); // 报错ReferenceError
    let bar = 2;

上面代码中,变量foo用var命令声明,会发生变量提升,即脚本开始运行时,变量foo已经存在了,但是没有值,所以会输出undefined。变量bar用let命令声明,不会发生变量提升。这表示在声明它之前,变量bar是不存在的,这时如果用到它,就会抛出一个错误。

let不允许在相同作用域内,重复声明同一个变量。

    // 报错    
    function afunc() {
        let a = 10;
        var a = 1;
    }
      
    // 报错
    function bfunc() {
       let a = 10;
       let a = 1;
    }

    var name = 'zzs'    
    while(true){
        var name = 'ncy'
        console.log(name)
        break
    }
    console.log(name)

var 两次输出的都是 ncy

    [Running] node "c:\web\single\test.js"    
    ncy
    ncy

ES6 let 实际上是javascript 增加了块级作用域 ,用let声明的变量 只在块级作用域内生效

    let name = 'zzs'    
    while(true){
        let name = 'ncy'
        console.log(name)
        break
    }
    console.log(name)

let两次分别输出 ncy  zzs

    [Running] node "c:\web\single\test.js"    
    ncy
    zzs

const也用来声明变量,但是声明的是常量。一旦声明,常量的值就不能改变。

    const PI = Math.PI     
    PI = 22

结果是 const定义的常量 再赋值 会编译错误

    [Running] node "c:\web\single\test.js"    
    c:\web\single\test.js:20
    PI = 22 //Module build failed: SyntaxError: /es6/app.js: "PI" is read-only
       ^
    TypeError: Assignment to constant variable.
        at Object.<anonymous> (c:\web\single\test.js:20:4)
        at Module._compile (internal/modules/cjs/loader.js:776:30)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
        at Module.load (internal/modules/cjs/loader.js:653:32)
        at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
        at Function.Module._load (internal/modules/cjs/loader.js:585:3)
        at Function.Module.runMain (internal/modules/cjs/loader.js:829:12)
        at startup (internal/bootstrap/node.js:283:19)
        at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
    [Done] exited with code=1 in 0.143 seconds

const有一个很好的应用场景,就是当我们引用第三方库时声明的变量,用const来声明可以避免未来不小心重命名而导致出现bug:

    const route= require('route')