JS关键词let、const、var

    更新时间: 2022-08-11 10:31:49
    点击量: 771
    标签: 前端js

    简介:js常量变量声明方式的区别

    文章均为个人原创, 搬运请附上原文地址感谢, 原文来自MasterYi博客

    关键词

    • 基本的关键词指针, 学过C语言的应该知道,我们的变量其实只是对应的内存单元地址的一个指针, 指针也就是内存地址

    var

    • 存在变量提升 (js 执行前var的变量会自动放置前方执行声明, 默认undefined)
    • 不存在块级作用域 (除了闭包函数体内)
    • 会给全局添加属性:浏览器的全局对象是window,Node的全局对象是global
    • 可以不设置初始值
    • 能改变指针方向
    • 允许重复声明, 会覆盖之前的声明
    • 因为无块级作用域某些场景会泄漏为全局变量
    /*---- 变量提升 ----*/
    console.log(a); // 变量提升不会报错, 打印undefined
    var a = 1;
    console.log(a, window.a); // 打印 1 1  var声明变量会给全局添加属性
    
    
    /*---- 块级作用域 ----*/
    if(true){
        var b = 1;
    }
    console.log(b); // 无块级作用域 打印 1
    
    
    function testb(){
        var c = 'a';
    }
    let testb_ = () => {
        var c = 1;
    }
    testb(); 
    console.log(c);  // 局部作用域 无论闭包还是箭头 都无法访问到 直接报致命错误
    
    
    /*---- 无类型声明 ----*/
    function testd(){
        d = 1;
    }
    testd();
    console.log(d, window.d);// 打印 1 1  这种不加声明类型的也会全局访问, 即便在函数体内声明也是如此
    
    
    /*---- 初始值 ----*/
    var e; // 不会异常, 默认值为undefined
    
    
    /*---- 重复声明 ----*/
    var f = 1;
    var f = 2; // 不会异常,覆盖前面声明的值
    
    
    /*---- 改变指针方向 ----*/
    var g = 1; 
    g = {}; // 允许改变指针方向
    • 使用var会泄漏为全局变量的场景
        for(var a = 1; a < 10 ; a++){
        }
        console.log(a); // 打印10 因为原有的var无块级作用域会泄漏为全局变量, 改为let即可
        
        if(true){
            var b = 1;
        }
        console.log(b); // 打印1 var无块级作用域会泄漏为全局变量
        
        var arr = [1, 2, 3]
        while (arr.length){
            var c = arr.pop();
        }
        console.log(c); // 打印 1  var无块级作用域会泄漏为全局变量
        
        switch (1){
            case 1:
                var d = 1;
        }
        console.log(d); // 打印 1  var无块级作用域会泄漏为全局变量

    let

    • 不存在变量提升, 未执行声明前不允许使用 直接报致命错误
    • 块级作用域
    • 可以不设置初始值
    • 能改变指针方向
    • 同一 作用域 下不允许重复声明
    /*---- 变量提升 ----*/
    // console.log(a); // 不存在变量提升,抛异常, 未执行声明前不允许使用, 也被称为暂时性死区
    let a = 1;
    console.log(a, window.a); // 打印 1 undefined  let声明变量不会给全局添加属性
    
    
    /*---- 块级作用域 ----*/
    let b = () => {
        console.log(`b`)
    }
    
    if(1){
        // console.log(b); // 此处如果使用b, 反而会抛一个异常, 此处知识就设计到了JS执行上下文和变量提升的问题了
        let b = 1; // 忽略上方那一行, 这里正常
        console.log(b); // 打印1 
    }
    console.log(b); // 打印() =>{ console.log(`b`) }
    
    
    /*---- 初始值 ----*/
    let c; // 不会异常, 默认值为undefined
    
    
    /*---- 重复声明 ----*/
    let d = 1;
    // let d = 2; // 同一作用域下, 会抛异常
    if(true){
        let d = 2; // 不会异常, 不在同一作用域了
    }
    
    /*---- 改变指针方向 ----*/
    let e = 1;
    e = {}; // 允许改变指针方向

    const

    • 不存在变量提升, 未执行声明前不允许使用 直接报致命错误
    • 块级作用域
    • 声明必须设置初始值
    • 不能改变指针方向
    • 同一作用域下不允许重复声明
    /*---- 变量提升 ----*/
    console.log(a); // 不存在变量提升,抛异常
    const a = 1;
    console.log(a, window.a); // 打印 1 undefined  const声明变量不会给全局添加属性
    
    
    /*---- 块级作用域 ----*/
    if(true){
        const b = 1;
    }
    console.log(b); // 块级作用域 抛异常
    
    
    /*---- 初始值 ----*/
    const c; // 必须有初始值, 抛异常
    
    
    /*---- 重复声明 ----*/
    const d = 1;
    // const d = 2; // 同一作用域下, 会抛异常
    if(true){
        const d = 2; // 不会异常, 不在同一作用域了
    }
    
    /*---- 改变指针方向 ----*/
    const e = {}; // 常量 C里面也称为常指针
    // e = 1; // 不允许改变指针方向, 会直接抛异常
    e['test'] = 1; // 正常, 因为指针方向没有改变,只是改变对象内部的属性值 
    
    const f = [];
    f.push(1); // 与上同理