【var const let区别】

var 、const 、let 区别

var 在 ECMAScript 所有版本中都可以使用。

let 和 const 只能在 ES6 及之后的版本中使用。

var
  • 函数作用域。

  • 声明未初始化时,值为undefined

  • 变量提升机制。

    在全局作用域中或还是在局部作用域中,使用var关键字声明的变量,都会被提升到该作用域最顶部。


    function test(status) {  
        if (status) {
            var value = "person";
        } else {
            console.log(value);
        }
        console.log(value);
    }
    test(false);
    

    if 代码块中的 var 声明的变量被提升到了函数的顶端。

    JS 引擎在代码预编译时,会自动将所有代码里面的var关键字声明的语句都提升到当前作用域的顶端。

    // 上面的代码被解析如下
    function test(status) {  
        var value;
        if (status) {
            value = "person";
        } else {
            console.log(value); // undefined
        }
        console.log(value); // undefined
    }
    test(false);
    

  • 块级声明:
    • 只在当前函数下声明的变量有效。
    • 在代码块和{}括号之内有效。

let
  • 块级声明,没有变量提升。

    function test(status) {  
        if (status) {
            let value = "person";
        } else {
            console.log(value); // 报错
        }
        console.log(value); // 报错
    }
    test(false);
    
  • 不允许同一个块级作用域中出现冗余声明。

    如果在同一个作用域中某个变量已经存在,再次使用let关键字声明会报错。

    var value = "test1";
    let value = "test1"; // SyntaxError
    

const
  • const 声明指常量,一旦定义就不能修改。

  • 常量必须初始化值,如果不初始化就会报错。

    const test; // error:Missing initializer
    
  • const 声明对象。

    const 变量不能修改指针,但可以修改值。

    const obj = {
        name: "person",
        age: 21
    }
    
    obj.name = "Danny"; // 没问题
    obj = {}; // error:不能修改对象指针
    

暂时性死区
console.log(typeof value); // error:Cannot access 'value' before initialization
let value = "person";

此时的 value 还处在 JS 所谓的暂时性死区(TDZ)。


声明之前的执行瞬间被称作暂时性死区。


**工作原理:**JS 引擎在扫描代码时发现变量声明时,如果遇到var会将他们提升到当前作用域的顶端,遇到letconst 就会将声明放到 TDZ 中,如果访问 TDZ 中的变量就会抛出错误,只有执行完 TDZ 中的变量才会将它移出,然后就可以正常访问。这种机制只会在当前作用域生效。


在不同作用域下:【此处有待深究学习】

console.log(typeof value); // undefined
if(true) {
    let value = "person";
}

三者最大区别
  • var 在全局作用域声明的变量有一种行为会挂在 window 对象上,它会创建一个新的全局变量作为全局对象的书信,这种行为可能会覆盖到 window 对象上的某个属性。
  • let const 则不会。
var value1 = "test1";
let value2 = "test2";
const value3 = "test3";
console.log(window.value1);
console.log(window.value2); // undefined
console.log(window.value3); // undefiend

for 循环中的运用
  • var 声明的变量没有块级作用域,迭代变量i会渗透到循环体外部。
for (var i = 0; i < 4; i ++) {
    // ...
}
console.log(i); // 4
  • let声明的迭代变量,作用域限制为 for 循环块内部。
for (let i = 0; i < 4; i ++) {
    // ...
}
console.log(i); // error

真题
for (var i = 0; i < 4; i ++) {
    setTimeout( () => {
        console.log(i);
    }, 0)
}
// 4 4 4 4 

setTimeout 异步执行,for 循环退出时 i 为 4.【深究学习】


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

JS 引擎在后台会为每个迭代循环声明一个新的迭代变量,每个 setTimeout 引用的都是不同的变量实例。


总结
  • var 声明的范围是函数作用域,let 声明的范围是块级作用域。
  • var 声明的变量会被提升到函数作用域的顶部,letconst 声明的变量不存在提升,且具有暂时性死区特征。
  • var允许在同一个作用域中重复声明同一个变量,letconst不允许。
  • 在全局作用域中,var声明的变量会被挂在为 window 对象的属性,letconst不会。
  • const 行为基本与 let 相同,但 const 声明的变量必须进行初始化,且不能修改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值