JS中let和var的区分

1. 定义变量

  • 声明语法

    var upperA = 'A';
    let upperB = 'B';
    const upperC = 'C';
  • 只声明不初始化的效果,【
    const定义的常量不能够修正,而且必需初始化。

    // var 声明变量
    var upperA;
    console.log('打印大写的A:%s', upperA);
    // 效果:打印大写的A:undefined
    
    // let 声明变量
    var upperB;
    console.log('打印大写的B:%s', upperB);
    // 效果:打印大写的B:undefined
    
    // const 声明常量
    const upperC;
    console.log('打印大写的C:%s', upperC);
    // 毛病:SyntaxError: Missing initializer in const declaration
  • 声明后值是不是可修正,【
    const定义的常量不能够修正,而且必需初始化。

    // var 声明变量初始化并修正值
    var upperA = 'A';
    console.log('打印upperA:%s', upperA);
    // 效果:打印upperA:A
    upperA = 'LetterA';
    console.log('打印upperA:%s', upperA);
    // 效果:打印upperA:LetterA
    
    // let 声明变量初始化并修正值
    var upperB = 'B';
    console.log('打印大写的B:%s', upperB);
    // 效果:打印upperB:B
    upperB = 'LetterB';
    console.log('打印大写的B:%s', upperB);
    // 效果:打印upperB:LetterB
    
    // const 声明常量初始化并修正值
    const upperC = 'C';
    console.log('打印upperC:%s', upperC);
    // 效果:打印upperC:C
    upperC = 'LetterC';
    console.log('打印upperC:%s', upperC);
    // 毛病:TypeError: Assignment to constant variable.
    

2. 变量提拔

  • 浏览器在运转代码之前会举行预剖析,起首剖析函数声明,定义变量,剖析完以后再对函数、变量举行运转、赋值等

    不管var声明的变量处于当前作用域的第几行,都邑提拔到作用域的头部。

    var 声明的变量会被提拔到作用域的顶部并初始化为undefined,而let声明的变量不会被提拔到作用域的顶部。

    console.log('打印upperA:%s', upperA);
    // 效果:打印upperA:undefined
    console.log('打印upperB:%s', upperB);
    // 毛病:ReferenceError: upperB is not defined
    var upperA = 'A';
    let upperB = 'B';
    

3. 是不是许可反复声明同一个变量

  • ** var许可在雷同作用域内,反复声明同一个变量,背面声明的变量会掩盖前面声明的变量。

    ** let不许可在雷同作用域内,反复声明同一个变量。

    var upperA = 'A';
    let upperB = 'B';
    // 反复声明
    var upperA = 'LetterA';
    let upperB = 'LetterB';
    console.log('打印upperA:%s', upperA);
    console.log('打印upperB:%s', upperB)
    // 毛病:SyntaxError: Identifier 'upperB' has already been declared

4. 作用域

  • 在ES6之前,我们都是用var来声明变量,而且JS只要函数作用域和全局作用域,没有块级作用域,所以{}限制不了var声明变量的接见局限。

    // ---------- 比方: ----------
    {
        var upperA = 'A';
    }
    console.log('打印upperA:%s', upperA);
    # 效果: 打印upperA:A
    
    // ---------- ES6新增的let,能够声明块级作用域的变量。----------
    {
        let upperB = 'B';
    }
    console.log('打印upperB:%s', upperB);
    // 毛病: ReferenceError: upperB is not defined

5. let合营for轮回的奇特运用

  • let异常合适用于 for轮回内部的块级作用域。

    ** JS中的for轮回体比较特别,每次实行都是一个全新的自力的块作用域,用let声明的变量传入到 for轮回体的作用域后,不会发作转变,不受外界的影响。

    // ---------- 看一个罕见的口试问题: ----------
    for (var i = 0; i <10; i++) {  
        setTimeout(function() {    // 同步注册回调函数到 异步的 宏使命行列。
            console.log(i);        // 实行此代码时,同步代码for轮回已实行完成
        }, 0);
    }
    // 输出效果:10   共10个
    // 这里面的知识点: JS的事宜轮回机制,setTimeout的机制等
    
    // ---------- 如果把 var改成 let声明:----------
    // i虽然在全局作用域声明,但是在for轮回体部分作用域中运用的时刻,变量会被牢固,不受外界滋扰。
    for (let i = 0; i < 10; i++) { 
        setTimeout(function() {
            console.log(i);    //  i 是轮回体内部分作用域,不受外界影响。
        }, 0);
    }
    // 输出效果:0  1  2  3  4  5  6  7  8 9  
    原文作者:jrue
    原文地址: https://segmentfault.com/a/1190000017535341
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞