var let const

146 阅读3分钟

「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」。

介绍

var、let、const都是用于声明变量,在很多情况下var和let可以互相代替达到声明的变量预期效果。声明变量时语法都一样。

var

使用var声明的变量,一般情况下不是函数作用域就是全局作用域,它声明的变量没有块级作用域。 var声明的变量时能够变量提升,example如下

    testVar();
    function testVar(){
        console.log(a);//undefined
        var a = 1;
        console.log(a);//1
    }

由于javaScript引擎在代码预编译阶段会自动将代码内的var关键字声明的语句提升到当前作用域最上面。

var声明的变量可以挂载到window对象上

    var c = 10;
    console.log(window.c);//10

let

声明变量作用于块级作用域,只在当前作用域中有效。声明的变量不会挂载到window对象上,不允许重复定义变量,不存在变量提升(会报错)

    let a = 10;
    console.log(window.a);//undefined
    testVar();
    function testVar(){
        //console.log(b);// Cannot access 'a' before initialization
        let b = 1;
        console.log(b);//1
    }
    

const

用于声明常量,它声明的常数变量分两种情况,一个是简单数据类型的常量,数值是不能改变的;在声明的值是引用数据类型时,是变量的地址不能改变而不是值不能变。example如下:

    //const obj = {name: 'zs',age: 20}
    //console.log(obj); //{ name: 'zs', age: 20 }
    
    const obj = {name: 'zs',age: 20}
    obj.name = 'ls'
    console.log(obj); //{ name: 'ls', age: 20 }

如何解决上述这种情况呢?一般情况下在单层对象结构时,可以使用Object.freeze()方法

    const obj = {name: 'zs',age: 20}
    Object.freeze(obj);
    obj.name = 'ww'
    console.log(obj); //{ name: 'zs', age: 20 }

当数据结构嵌套比较复杂时,就需要自己使用递归的方式做深层次冻结方法了,在这里简单实现了一下深层次冻结方法:

    /**
     * 深层次冻结复杂结构数据
     * @param {*} obj 
     */
    function deepFreeze(obj){
        Object.freeze(obj);
        for(let key in obj){
            // 判断key不属于原型链上的key
            if(obj.hasOwnProperty(key)){
                if(typeof obj[key] === 'object'){
                    deepFreeze(obj[key]);
                }
            }
        }
    }
   const deepObj = {
        name: 'zs',
        age: 10,
        like: {
            foot: '香蕉'
        }
    } 
    Object.freeze(deepObj);
    deepObj.like.foot = 'apple';
    console.log(deepObj);//{ name: 'zs', age: 10, like: { foot: 'apple' } }
    deepFreeze(deepObj);
    deepObj.like.foot = 'apple';
    console.log(deepObj);// { name: 'zs', age: 10, like: { foot: '香蕉' } }

区别

var和let/const区别

作用域问题: var没有块级作用域,有函数和全局作用域;let和const是块级作用域 挂载问题: var声明的变量,一般不指定挂载对象时,挂载在window对象上,而let和const不会挂载window对象上。

    var c = 10;
    console.log(window.c);//10
    let a = 10;
    console.log(window.a);//undefined

变量提升问题:var声明的变量,都会被提升到该作用域的最顶部;而let和const关键字声明的变量则不可以。 重复声明问题:var 支持同一个变量名可以多次声明;let和const声明的变量名不允许重复

let和const区别

let声明的变量可以改变,值和类型都可以改变;const声明的常量不可以改变