zoukankan      html  css  js  c++  java
  • 彻底理解 let 与 const 的用法

    ES6 新增了两个声明两个声明标识符的方式: let 和 const。

    • let 用来声明变量,并且会在当前作用域形成 代码块
    • conts 用来声明常量,所谓常量就是物理指针不可以更改的变量。

    其实我个人是没有其他语言基础的,第一次看到这两个定义,瞬间懵逼有没有。代码块是什么鬼? 物理指针还能勉强理解。

    • 所谓代码块,大可不必感觉它有多么高深。在JS中你想形成代码块最简单的做法就是 :
    {
        let a = 1;
    }
    console.log(a)  // 报错 a is not defined
    

    也就是说 你只需要用 {} 包起来,这个 {} 就是一个代码块。


    let

    好,接下来介绍下 let 的特性,使用 let 声明的变量,只能在当前代码块中访问和使用,有些类似于函数作用域,但是它又有几点不同的地方。

    • let 声明变量,变量不会被提升。
    function fn1(){
        console.log(a);
        let a = 1;
    }
    fn1();  // 报错
    
    var b = 2;
    function fn2(){
        console.log(b);
        let b = 1;
    }
    fn2();  // 报错
    
    • for 循环中 使用let 定义变量,只在for的循环周期内可以使用。
    // 在ES5 中如果想使用for循环每次的i需要使用闭包的特性
    var arr = [];
    for(var i=0; i<5; i++){
        arr.push(function(){
            console.log(i);
        })
    }
    arr[1]()  // 5
    arr[2]()  // 5
    arr[3]()  // 5
    arr[4]()  // 5
    
    /*
        为什么每次都是5,因为for循环每次做的事只是向数组中存入一个函数,这个函数的功能是 打印 i,但是函数并没有立刻执行。而这个i是通过var i 这句话来声明的。当for循环跑完,咱们都知道此时 i 的值是5。所以当你去执行函数的时候,自然打印出5.
    */
    
    

    如果想使用每次循环中的i的值 可以利用ES5的闭包:

    var arr = [];
    
    for(var i=0; i<5; i++){
        arr.push((function (a){
            return function (){
                console.log(a);
            }
        })(i))
    }
    arr[1]()  // 1
    arr[2]()  // 2
    arr[3]()  // 3
    
    // 以上写法等价于下面这种写法,注意参数i和形参i,此i非彼i
    /*
        for(var i=0; i<5; i++){
            (function (i){
                arr.push(function (){
                    console.log(i)
                })
            })(i)
        }
    */
    

    如果使用ES6提供的let来声明变量,那么就会变得so easy

    var arr = [];  // let arr = [] 都可以
    for(let i=0; i<5; i++){
        arr.push(function (){
            console.log(i)
        })
    }
    arr[0]()  // 0
    arr[1]()  // 1
    arr[2]()  // 2
    

    一些朋友可能会觉得特别不适应。为什么这样就能弹出 0, 1, 2?其实需要注意个问题,就是这个let i = 0; 声明的位置,是在 for的() 内,那么你可以理解成,在 for 的内部 就定义了一个 i 而且是使用 let 定义的。所以每次循环就相当于在当前循环的i值的前提下向数组push的。

    所以大家在使用的时候需要注意以下几个问题:

    let i; 
    for(i = 0; i < 5; i++){
        setTimeout(function(){
            console.log(i);  //  5 5 5 5 5
        },1000)
    }
    

    不同于:

    for(let i = 0; i < 5; i++){
        setTimeout(function(){
            console.log(i);  //  0 1 2 3 4
        },1000)
    }
    

    const

    const 除了不能改变物理指针的特性,其他特性和 let 一样。

    当声明普通数据类型的时候,那么一但声明了,就不可以再改变。

    const a = 1;
    
    a = 2;  //Uncaught TypeError: Assignment to constant variable.
    

    当声明复杂数据类型的时候,物理指针不可以改变,但是可以改变数据内的属性值,以及可以给数据添加新属性等操作。

    const o = {a: 1};
    
    o.a = 2;
    o.b = 3;
    
    console.log(o);
    
    o = {};  // 报错
    
    

    最后还有一个值得注意的问题:在ES6中不存在函数提升,算是修复了ES5得一个bug

    看个例子:

    // ES5 
    function a(){
        console.log(1);
    }
    function fn(){
        a();
        if(false){
            function a(){
                console.log(2)
            }
        }
    }
    fn();  // 无理由报错 找不到a,个人认为很不合理!
    
    
    // ES6
    "use strict"
    function a(){
        console.log(1);
    }
    function fn(){
        a();
        if(false){
            function a(){
                console.log(2)
            }
        }
    }
    fn();
    
    
  • 相关阅读:
    开源协议
    开发新技能
    UML 思维导图 思维脑图 xmind
    小方法
    Android Service
    JS 下载图片
    quartz任务执行完之后再执行下一轮任务
    easyui 下边有滚动条问题
    微信支付证书 系统找不到指定的文件
    Swiper 动态加载数据没有变化问题
  • 原文地址:https://www.cnblogs.com/copperhaze/p/6145302.html
Copyright © 2011-2022 走看看