美文网首页
JavaScript之let和const命令

JavaScript之let和const命令

作者: 又菜又爱分享的小肖 | 来源:发表于2021-06-26 16:27 被阅读0次

基本用法

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

        {
            let a = 1;
            var b = 2;
        }
        console.log(a); //error: a is not defined
        console.log(b); //2

以上例子说明let声明的变量只能在所在代码块有效

for循环非常适合使用let, 以下是使用var的一个for循环

        for(var i = 0;i < 10;i++){
            console.log(i);// 0,1,2,3,4,5,6,7,8,9
        }
        console.log(i);// 10

上面代码中, 因为变量i是用var声明的,所以全局都有效, 每循环一次变量i都发生了变化, 这时候小伙伴会问为什么外部打印的不是9吗?怎么会是10呢?
因为在循环打印的时候因为是 i++ ; i++是先执行后+1的,当打印9的时候,这时候的下一步就已经+1了,所以外部变量打印的10.

如果使用let, 声明的变量仅在块级作用域内有效,最后将输出 i is not defined

        for(let i = 0;i < 10;i++){
            console.log(i); // 0,1,2,3,4,5,6,7,8,9
        }
        console.log(i); //error: i is not defined

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

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

这说明函数内部的变量 i 与循环变量 i 不在一个作用域, 而是有各自单独的作用域, 所以在开发中一定要避免在for循环中声明与for循环一样的变量

不存在变量提升

var命令会发生变量提升的现象, 既变量可以在声明之前使用, 值为 undefined. 这种有点奇怪, 按照一般的逻辑
变量应该在声明语句之后才可以使用

        console.log(a); // undefined
        var a = '肖某';

        console.log(a); // 报错
        let a = '肖某';

以上代码中, 变量a用var命令声明会发生变量提升,既脚本开始运行时, 变量a就已经存在, 但是没有值, 所以会输出undefined . 变量a用let声明则不会发生变量提升, 表示这个变量是不存在的,如果用到他, 会抛出错误

暂时性死区

只要块级作用域内存在let命令. 它所声明的变量就一定在这个区域, 不再受外部影响

        var a = '肖某';
        if(true){
            a = '123';
            let a;
            console.log(a);//报错
        }

ES6明确规定, 如果区块内存在let和const命令, 则这个区块对这些命令声明的变量从一开始就是封闭作用域, 只要在声明前使用这些变量, 就会报错

不允许重复声明

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

        function num(){
            let a = 10;
            var a = 10; //报错
        }

        function num(){
            let a = 10;
            let a = 10; //报错
        }

不能在函数内容重新声明参数

       function num(a){
           let a; //报错
       }

       function num(a){
           {
               let a; //不报错  在一个独立的块级作用域内 ,不受外部影响
           }
       }

为什么需要块级作用域

如果没有块级作用域, 会导致很多场景不合理
第一种场景, 内层变量可能会覆盖外层变量

        var a = new Date();
        function f() {
            console.log(tmp);
            if(false) {
                var a = '肖某';
            }
        }
        f(); // undefined

 // 本质
        function f() {
            var a; // 变量提升 使变量a提升到函数顶部
            console.log(a);
            if(false) {
                var a = '肖某';
            }
        }

第二种场景, 用来计数的循环变量泄露与全局变量

        var s = 'hello';
        for (var i = 0; i < s.length;i++){
            console.log(s[i]);
        }
        console.log(i); // 5

变量 i 只用来控制循环, 但是循环结束后, 它并没有消失, 而是泄露成了全局变量

const命令

const 声明一个只读的变量. 一旦声明, 常量的值就不能改变

        const a = '肖某';
        a = 3; //报错

只声明, 不赋值也会报错

        const a; //报错

const 的作用域于let相同: 只在声明所在的块级作用域有效 没有变量提升, 也存在暂时性死区, 只能在声明后使用

        if(true) {
            const a = 3;
        }
        console.log(a); //报错
本质

const 实际上保证的并不是变量的值不能改动, 而是变量指向的那个内存地址不得改动. 对于简单数据类型 (数值, 字符串, 布尔值) 而言, 值就保存在变量指向的内存地址中,因此等同于常量. 但对于复合类型的数据 (主要是对象和数组) 而言, 变量指向的内存地址保存的只是一个指针, const只能保证这个指针是固定的,在至于它指向的数据结构是不是可变的,这完全不能控制, 因此将一个对象声明为常量时必须小心

        const obj = new Object();
        //为obj对象添加一个属性,可以改动成功
        obj.name = '肖';
        obj.age = 21;

        //将obj指向另外一个对象, 就会报错
        obj = {}; //报错

如果你想让const 声明的对象不能修改,可以用Object.freeze方法进行冻结

       const obj = Object.freeze({});
       obj.name = '肖'; //报错

除了将对象本身冻结,还要将对象的属性冻结

        const obj = {
            name: '肖',
            age: 21
        };
        var constantize = obj => {
            Object.freeze(obj);
            Object.keys(obj).forEach((key, i) =>{
                if(typeof obj[key] === 'object'){
                    constantize(obj[key]);
                }
            })
        }
        constantize(obj);

相关文章

  • ES6基础

    let和const let 命令 (实际上为javascript新增了块级作用域)1、let命令用来申明变量,类似...

  • JavaScript之let和const命令

    基本用法 ES6新增了let命令,用法类似于var,但是所声明的变量只在let所在的代码块有效 以上例子说明let...

  • 第1章ES6初步

    目标 ES6简介 ECMAScript 和 JavaScript 的关系 let命令 块级作用域 const命令 ...

  • 第1章ES6初步

    目标 ES6简介 ECMAScript 和 JavaScript 的关系 let命令 块级作用域 const命令 ...

  • let和const

    新的赋值语句let和const let和const命令

  • ES6之 let 和 const 命令

    ES6 之 let 和 const 命令 1、let 命令 1.1、基本用法 ES6 新增了let命令,用来声明变...

  • ES6的let 和 const 命令

    let 和 const 命令 let 命令 块级作用域 const 命令 顶层对象的属性 gl...

  • var、let、const

    JavaScript中的变量声明目前有三种:var、let、const。let和const是JavaScript里...

  • ES6需要记忆理解的地方

    let和const命令 1、let和const均无变量提升。2、let变量指向的地址可变,const指向的地址不可...

  • 重读 ES6(一)

    一、let 和 const 命令 let 命令 let 与 var 的区别:let 声明的变量只在 let 命令所...

网友评论

      本文标题:JavaScript之let和const命令

      本文链接:https://www.haomeiwen.com/subject/sklzyltx.html