当前位置: 首页 > news >正文

JavaScript 变量声明:var vs let vs const详情

在 JavaScript 中,变量声明经历了从 varlet/const 的演变。ES6(2015)引入的 letconst 解决了 var 的关键缺陷。接下来我们一起看看三者的区别。


一、核心区别速览
特性varletconst
作用域函数作用域块级作用域块级作用域
重复声明✅ 允许❌ 禁止❌ 禁止
变量提升✅ 提升⚠️ 暂时性死区⚠️ 暂时性死区
初始值可不初始化可不初始化❌ 必须初始化
重新赋值✅ 允许✅ 允许❌ 禁止

二、详解关键特性
  1. 作用域(Scope)

    • var:函数作用域
      仅在函数内部创建新作用域,在 if/for 等块中会泄漏到外部:

      function run() {if (true) {var x = 10;}console.log(x); // 10(泄漏到函数作用域)
      }
      
    • let/const:块级作用域
      只在 {} 块内有效:

      if (true) {let y = 20;const z = 30;
      }
      console.log(y); // ReferenceError
      console.log(z); // ReferenceError
      
  2. 重复声明

    • var 允许重复声明(易引发 bug):
      var a = 1;
      var a = 2; // 不报错
      
    • let/const 禁止重复声明
      let b = 5;
      let b = 10; // SyntaxError
      
  3. 变量提升(Hoisting)

    • var 提升且初始化为 undefined
      console.log(c); // undefined
      var c = 15;
      
    • let/const 存在暂时性死区(TDZ)
      声明前访问会报错:
      console.log(d); // ReferenceError
      let d = 25;
      
  4. 常量性质

    • const 必须初始化且不能重新赋值
      const PI = 3.14;
      PI = 3.14159; // TypeError
      
    • 注意:const 定义的对象/数组内容可修改(绑定关系不变):
      const user = { name: "Alice" };
      user.name = "Bob"; // ✅ 允许
      user = { name: "Eve" }; // ❌ TypeError(重新赋值)
      

三、最佳实践指南
  1. 默认使用 const
    适用于所有不需要重新赋值的变量(避免意外修改)。

    const API_URL = "https://api.example.com";
    const MAX_ITEMS = 100;
    
  2. 需要重新赋值时用 let
    替代循环计数器等场景中的 var

    for (let i = 0; i < 5; i++) {console.log(i); // i 只在循环块内有效
    }
    
  3. 避免使用 var
    除非维护旧代码,新项目优先使用块级作用域变量。

  4. 全局变量注意
    var 在全局作用域会挂载到 window 对象,let/const 不会:

    var globalVar = "old";
    let globalLet = "new";
    console.log(window.globalVar); // "old"
    console.log(window.globalLet); // undefined
    

四、关键示例对比
// 作用域对比
function scopeTest() {if (true) {var varVar = "var";let letVar = "let";}console.log(varVar); // "var"(泄漏)console.log(letVar); // ReferenceError
}// 循环中的闭包问题(经典面试题)
for (var i = 0; i < 3; i++) {setTimeout(() => console.log(i), 100); // 输出 3, 3, 3
}for (let j = 0; j < 3; j++) {setTimeout(() => console.log(j), 100); // 输出 0, 1, 2
}

总结
  • var:历史遗留,存在作用域泄漏和提升问题,现代开发中应避免
  • let:块级作用域,需重新赋值时的首选(如循环计数器)。
  • const:块级作用域,声明常量或引用类型时的默认选择。

迁移建议:在新项目和 ES6+ 环境中全面采用 let/const,使用 linter 工具(如 ESLint)强制禁用 var

通过理解这些差异,你可以减少变量相关 bug,写出更清晰、更稳定的 JavaScript 代码!

相关文章:

  • 如何使用windows下的vscode连接到本地虚拟机的linux
  • 数据库概念
  • 第二章支线二:浮空之域:布局法则深研
  • C与C++相互调用
  • C++继承与构造函数调用详解
  • MySQL中怎么看是否走了索引
  • springboot java.lang.ClassNotFoundException: dm.jdbc.driver.DmDriver应该如何解决
  • Java Spring 之拦截器HandlerInterceptor详解与实战
  • 解决方案:__cplusplus宏的值始终为199711L(即 C++98)
  • 分布式存储技术全景解析:从架构演进到场景实践
  • 循环神经网络(RNN)全面教程:从原理到实践
  • 图解深度学习 - 基于梯度的优化(梯度下降)
  • 学习STC51单片机21(芯片为STC89C52RCRC)
  • 历年西北工业大学计算机保研上机真题
  • DrissionPage WebPage模式:动态交互与高效爬取的完美平衡术
  • 使用原生前端技术封装一个组件
  • 近期手上的一个基于Function Grap(类AWS的Lambda)小项目的改造引发的思考
  • Feign服务注册到nacos 2.2.3
  • Spring中过滤器 RequestContextFilter 和 OncePerRequestFilter 的区别
  • 基于CNN的OFDM-IM信号检测系统设计与实现
  • 武汉做网络营销的公司/网络优化培训骗局
  • 网站快速收录方法/超级外链工具
  • 合肥公司网站设计/免费网页制作平台
  • php做网站评价/今天疫情最新消息
  • 个人网站 可以做论坛吗/百度一下官网入口
  • 建设银行个人网站个人客户/湖南株洲疫情最新情况