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

JavaScript 中 var、let、const 的核心区别与实战应用

要理解constvarlet的区别,我们可以从作用域、变量提升、可重复声明、可修改性这几个核心维度展开,这些也是新手最容易混淆的点。

一、核心概念铺垫

首先明确两个基础概念,能帮你更好理解区别:

  • 函数作用域:变量只在声明它的函数内部可访问(var是函数作用域)。
  • 块级作用域:变量只在声明它的{}内部可访问(let/const是块级作用域,{}包括if/for/while/ 普通代码块)。
  • 变量提升:JS 引擎在执行代码前,会把变量声明 “提升” 到当前作用域顶部(但赋值不会提升)。

二、逐个拆解 + 对比

1. var(ES5 语法)

var是 ES5 中声明变量的方式,特性如下:

  • 作用域:函数作用域(无块级作用域)。
  • 变量提升:声明会被提升,且提升后默认值为undefined
  • 可重复声明:同一作用域内可重复声明同一个变量,后声明的会覆盖前一个。
  • 可修改:声明后可随意修改值。

示例代码

// 1. 函数作用域(无块级作用域) if (true) { var a = 10; } console.log(a); // 输出 10(a 跳出了 if 的 {},因为 var 无块级作用域) // 2. 变量提升 console.log(b); // 输出 undefined(声明提升了,赋值没提升) var b = 20; // 3. 可重复声明 var c = 30; var c = 40; console.log(c); // 输出 40(后声明的覆盖前一个) // 4. 可修改 var d = 50; d = 60; console.log(d); // 输出 60
2. let(ES6 语法)

let是 ES6 为解决var的缺陷新增的声明方式,特性如下:

  • 作用域:块级作用域(被{}限制)。
  • 变量提升:存在 “暂时性死区(TDZ)”—— 声明也会提升,但提升后不会赋值undefined,在声明前访问会报错。
  • 不可重复声明:同一作用域内不能重复声明同一个变量(包括不能和var/const重复)。
  • 可修改:声明后可修改值。

示例代码

// 1. 块级作用域 if (true) { let a = 10; } console.log(a); // 报错:a is not defined(a 被 if 的 {} 限制,外部访问不到) // 2. 暂时性死区 console.log(b); // 报错:Cannot access 'b' before initialization let b = 20; // 3. 不可重复声明 let c = 30; // let c = 40; // 报错:Identifier 'c' has already been declared // var c = 40; // 同样报错 // 4. 可修改 let d = 50; d = 60; console.log(d); // 输出 60
3. const(ES6 语法)

const用于声明常量,特性和let基本一致,核心区别是不可修改

  • 作用域:块级作用域(和let完全一样)。
  • 变量提升:同样有暂时性死区(和let完全一样)。
  • 不可重复声明:和let完全一样。
  • 不可修改:声明时必须赋值,且赋值后不能修改引用(注意:如果是对象 / 数组,内部属性 / 元素可修改)。

示例代码

// 1. 块级作用域 if (true) { const a = 10; } console.log(a); // 报错:a is not defined // 2. 暂时性死区 console.log(b); // 报错:Cannot access 'b' before initialization const b = 20; // 3. 不可重复声明 const c = 30; // const c = 40; // 报错 // 4. 声明时必须赋值 // const d; // 报错:Missing initializer in const declaration // 5. 不可修改引用(重点) const e = 50; // e = 60; // 报错:Assignment to constant variable. // 注意:对象/数组的内部可修改(只是引用不能变) const obj = { name: "张三" }; obj.name = "李四"; // 正常执行,输出 { name: '李四' } console.log(obj); const arr = [1, 2]; arr.push(3); // 正常执行,输出 [1,2,3] console.log(arr);

三、核心区别对比表

特性varletconst
作用域函数作用域块级作用域块级作用域
变量提升有(提升为 undefined)有(暂时性死区)有(暂时性死区)
重复声明允许不允许不允许
声明后赋值允许(默认 undefined)允许(默认未初始化)不允许(必须立即赋值)
修改值允许允许引用不可改(对象 / 数组内部可改)

四、实际开发中的使用建议

  1. 优先用const:声明不需要修改的变量(如常量、固定引用的对象 / 数组),能减少代码意外修改的风险。
  2. 其次用let:声明需要修改的变量(如循环变量、状态变量)。
  3. 完全不用varvar的函数作用域和变量提升容易导致 bug(比如循环变量泄露、重复声明覆盖),ES6 后已被let/const替代。

let 和 const 取代var

letconst是 ES6 新增的变量声明方式,核心是解决var的作用域和提升问题,它们的使用场景可以用一句话概括:优先用const,需要修改时用let。下面结合具体场景和代码示例,帮你彻底分清什么时候用哪个。

一、const 的使用场景(优先选择)

const声明的是引用不可变的变量(声明时必须赋值,且不能重新赋值),适合以下所有 “不需要修改值 / 引用” 的场景:

1. 声明常量(固定不变的值)

比如数学常量、配置项、固定字符串等,用const能明确表示 “这个值不会变”,减少代码意外修改的风险。

// 数学常量 const PI = 3.1415926; const RADIUS = 5; const AREA = PI * RADIUS * RADIUS; // 计算后的值也不变 // 配置项(固定的接口地址、密钥等) const BASE_URL = 'https://api.example.com'; const TOKEN = 'abc123456'; // 固定字符串 const TITLE = '个人信息'; // 就像你之前写的标题文本
2. 声明不需要重新赋值的对象 / 数组

注意:const只是限制 “引用不可变”,对象 / 数组的内部属性 / 元素可以修改,这种场景非常适合用const(因为你只是操作内部,不会重新赋值整个对象 / 数组)。

// 个人信息对象(只会改内部属性,不会重新赋值) const userInfo = { name: '韩雨龙', class: '24专本软件', hobby: ['唱歌', '跳舞'] }; // 允许修改内部属性(符合 const 规则) userInfo.name = '小雨'; userInfo.hobby.push('爬山'); // 列表数据(只会增删元素,不会重新赋值数组) const list = ['苹果', '香蕉']; list.push('橙子'); // 正常执行
3. 声明 DOM 元素(创建后不会重新赋值)

就像你之前写的创建h2元素,创建后只会修改它的文本 / 样式,不会重新赋值成另一个元素,所以用const最合适。

// 创建 h2 元素(不会重新赋值,用 const) const h2 = document.createElement('h2'); h2.textContent = '个人信息'; // 只是修改属性,不是重新赋值 document.body.appendChild(h2); // 创建按钮元素(同理) const btn = document.createElement('button'); btn.textContent = '点击'; document.body.appendChild(btn);

二、let 的使用场景(仅当需要修改时)

let声明的是可重新赋值的变量,只有当你需要 “修改变量的值 / 引用” 时,才用let,常见场景如下:

1. 循环变量(值会不断变化)

for/while循环中的计数器(比如i),每次循环都会修改值,必须用let(不能用const,因为i++是重新赋值)。

// for 循环计数器(i 会从 0 变到 4,需要修改) const info = ['班级', '学号', '姓名', '性别', '爱好']; for (let i = 0; i < info.length; i++) { const p = document.createElement('p'); p.textContent = info[i]; document.body.appendChild(p); } // while 循环变量 let count = 0; while (count < 3) { console.log('计数:', count); count++; // 重新赋值,必须用 let }
2. 状态变量(值会动态变化)

比如开关状态、计数器、表单输入值等,这些值会随着操作(点击、输入)变化,需要用let

// 开关状态(点击按钮切换 true/false) let isShow = false; const btn = document.createElement('button'); btn.textContent = '显示/隐藏'; btn.onclick = function() { isShow = !isShow; // 重新赋值,用 let console.log('状态:', isShow); }; document.body.appendChild(btn); // 计数器(点击一次加 1) let num = 0; const countBtn = document.createElement('button'); countBtn.textContent = '计数'; countBtn.onclick = function() { num++; // 重新赋值,用 let countBtn.textContent = `计数:${num}`; }; document.body.appendChild(countBtn);
3. 临时变量(需要重新赋值)

比如分步计算的值、条件判断后需要修改的变量,这些场景需要多次赋值。

// 分步计算总价 let total = 0; total += 10; // 加商品1价格 total += 20; // 加商品2价格 total *= 0.8; // 打8折(多次重新赋值,用 let) console.log('总价:', total); // 条件赋值(根据条件修改变量) let message = ''; const isLogin = false; if (isLogin) { message = '欢迎登录'; } else { message = '请先登录'; // 重新赋值,用 let }

三、避坑提醒(新手常错)

  1. ❌ 错误:用const声明需要修改的变量
const i = 0; i++; // 报错:Assignment to constant variable.(const 不能重新赋值)
  1. ❌ 错误:没必要用let声明不修改的变量
// 标题文本不会改,应该用 const 而不是 let let TITLE = '个人信息';

总结

  1. 优先用const:所有不需要重新赋值的场景(常量、对象 / 数组、DOM 元素、固定字符串等),用const能让代码更安全、语义更清晰。
  2. 仅用let:只有当变量需要重新赋值时(循环变量、状态变量、临时变量等),才用let
  3. 核心原则:能不用let就不用,用const约束 “不变”,用let表示 “可变”,彻底抛弃var
http://www.jsqmd.com/news/458090/

相关文章:

  • 25 Byte Buddy 注解完全指南:让动态生成的类“骗”过 Spring 和 JUnit
  • 盒马鲜生卡使用和回收攻略:你不知道的隐藏功能大揭秘 - 团团收购物卡回收
  • 用conda命令对已有环境进行迁移
  • SpringBoot+Vue 本庄村果园预售系统平台完整项目源码+SQL脚本+接口文档【Java Web毕设】
  • OpenClaw小龙虾爆火!B端运维成本将如何被这AI“龙虾”颠覆?
  • 2026年天虹提货券回收平台推荐与排行榜 - 淘淘收小程序
  • 企业微信接入openclaw--解决官方文档安装遇到的问题
  • 2026最新宁夏特色婚纱照摄影工作室推荐!银川优质摄影机构权威榜单发布 - 十大品牌榜
  • 一行 log 日志,结果引发了 P1 的线上事故...
  • 【IEEE出版 | EI检索】第八届信息科学、电气与自动化工程国际学术会议(ISEAE 2026)
  • 【Openclaw完全指南系列】第二篇:OpenClaw 13000 个 skills,用这些就够了!
  • 2026年小程序开发服务商甄选指南:北京定制化技术团队深度解析 - 品牌2026
  • 2026最新宁夏婚纱摄影服务公司推荐!银川优质摄影机构权威榜单发布 - 十大品牌榜
  • 【学术前沿】2026年内燃机技术与能源动力工程国际学术会议 (ICTEPE 2026) 征稿开启!附热效率仿真代码
  • 2026年微信小程序开发避坑指南:如何甄选靠谱的北京定制服务商 - 品牌2026
  • 网络安全面试题大全:从SQL注入到应急响应,助你轻松拿下心仪offer
  • 中国县域统计年鉴数据(2000-2023)汇总 - 21类县域数据免费获取
  • 【JVM】编译执行与解释执行的区别是什么?JVM 使用哪种方式?
  • 2026年热门的澳洲移民材料筹备公司推荐:澳洲移民政策解读/澳洲移民签证办理/澳洲移民留学对接生产厂家推荐几家 - 品牌宣传支持者
  • 智能化时代,网络安全的下一个十年
  • 2026最新宁夏婚纱照工作室推荐!银川优质婚纱摄影机构权威榜单发布 - 十大品牌榜
  • 2026年质量好的氢氟酸反应釜品牌推荐:搪玻璃反应釜/山东喷涂PFA反应釜/山东氢氟酸反应釜厂家推荐与采购指南 - 品牌宣传支持者
  • 网络安全职业规划:渗透测试vs安全服务工程师,应届生如何选择高薪方向?建议收藏!
  • 别骗自己了:始终困在原地,是你亲手写的结局
  • Day 01 Docker是什么?5分钟带你看懂容器革命
  • 基于SVPWM的飞轮控制系统的simulink建模与仿真
  • 数据库自动化的投资回报率:量化自动化调优、补丁与优化的商业价值
  • 樽海鞘优化算法 SSA (matlab代码,包含23个常用的基准测试函数)可直接运行效果如图所示
  • SpringBoot+Vue springcloud微服务车联网位置信息管理软件平台完整项目源码+SQL脚本+接口文档【Java Web毕设】
  • AI+热设计