var、let和const简单总结

本文详细对比了JavaScript中var、let和const三种变量声明方式的特点,包括它们的作用域、是否允许重新声明及赋值等关键特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

varletconst

很久不写JavaScript了, 对新的特性也不甚了解, 其实也不算新了, 看了一篇介绍定义变量的关键词的文章, 这里记录一下, 以便以后查阅.

在以前var适用于所有场景, 唯一的对手是``, 也就是没有修饰符.

对于函数外的场景, 二者是一致的, 区别在于在函数内部.

var的特性

  1. 全局作用域

    var hello = 'hello'
    
    function world() {
        var abc = hello
        console.log(abc)
    }
    world()  // hello
    复制代码

    由于hello是全局的, 所以在world方法中可以访问.

  2. 函数级作用域

    function world() {
        var abc = 'hello'
        console.log(abc)
    }
    world() // hello
    console.log(abc) // ReferenceError: abc is not defined
    复制代码

    由于abc的作用域是函数内部, 所以在函数外部无法访问在函数内部通过var声明的变量.

  3. 可被重新声明

    var abc = 'hello'
    var is_postive = true
    if (is_postive) {
        var abc = 'world'
    }
    console.log(abc) // world
    复制代码
  4. 可被重新赋值

    var abc = 'hello'
    abc = 'world'
    
    console.log(abc) // world
    复制代码
  5. 变量提升

    console.log(abc) // undefined
    var abc = 'hello'
    复制代码

    实际上它是被解释成这样执行的:

    var abc;
    console.log(abc); // abc未定义
    abc = 'hello'
    复制代码

    所以, 其实abc的声明是被提升到了最顶部, 但是赋值是undefined.

let的特性

  1. 全局作用域

    let abc = 'hello'
    
    function hello() {
        console.log(abc)
    }
    hello() // hello
    复制代码

    代码块外部的let, 作用域范围和var一样, 是全局的.

  2. 块作用域

    所谓块, 是指代码块. 具体就是在代码中被{}包起来的部分. 要区别于前面说的var的函数级作用域.

    let is_postive = true
    if (is_postive) {
        let abc = 'hello'
    }
    console.log(abc) // ReferenceError: abc is not defined
    复制代码

    注意这里和前面的变量提升部分的区别, 变量被提升后, 因为已经“声明”, 所以不会报错, 只是值变成了undefined, 而这里是纯粹的没有声明, 所以会报一个引用错误.

    let abc = 'hello'
    let is_postive = true
    if (is_postive) {
        let abc = 'world'
        console.log(abc) // world
    }
    console.log(abc) // hello
    复制代码

    从这里可以看出, 全局的abc和代码块中的abc是互不影响的.

  3. 不可被重新声明

    为了解决var声明的变量可以被重复声明的问题, 才引入了let, 所以

    let abc = 'hello'
    let abc = 'world' // SyntaxError: redeclaration of let abc
    复制代码
  4. 可被重新赋值

    这个特性其实是区别于const

    let abc = 'hello'
    abc = 'world'
    console.log(abc) // world
    复制代码
  5. 变量提升

    变量提升到顶部和var相同, 但它并没有被赋值undefined, 其实它并没有被初始化, 所以

    console.log(abc)
    let abc = 'hello' // ReferenceError: can't access lexical declaration `abc' before initialization
    复制代码

    值得一提的是, 只有在上下文存在对abclet形式的赋值时, 才会报上述错误, 如果仅仅是console.log(cde)这种, 其实和在其下面使用var声明变量效果一样.

const的特性

  1. 全局作用域

    varlet

  2. 块作用域

    let

  3. 不可被重新声明

    其实可以理解成PHP中的const(常量), 声明和赋值必须在同一条语句, 一旦完成, 就不可改变(限作用域内).

    const abc = 'hello'
    const abc = 'world' //SyntaxError: redeclaration of const abc note: Previously declared at line 1, column 6
    复制代码

    前提是在相同作用域内

    const abc = 'hello'
    
    if (true) {
        const abc = 'world'
        console.log(abc) // world
    }
    console.log(abc) // hello
    复制代码
  4. 不可被重新赋值

    const abc = 'hello'
    abc = 'world' // TypeError: invalid assignment to const `abc'
    复制代码

    但如果用const声明的变量是对象时

    const abc = {'k1': 'v1', 'k2': 'v2'}
    console.log(abc) //Object { k1: "v1", k2: "v2" }
    abc.k1 = 'v3'
    console.log(abc) //Object { k1: "v3", k2: "v2" }
    复制代码

    当然, 这种情况下重新给变量整体赋值还是不允许的

  5. 变量提升

    let

总结

关键词全局作用域函数作用域块作用域重新声明重新赋值
varYESYESNOYESYES
letYESNOYESNOYES
constYESNOYESNONO

转载于:https://juejin.im/post/5b9a56c15188255c5121adaa

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值