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

为什么需要let和const?

var、let、const主要在作用域、可变性、变量提升等方面有主要区别,可应用于不同的需求场景

  • let 和 const 引入了块级作用域(block scope),是 ES6 推荐的变量声明方式。
  • var 使用的是函数作用域(function scope),存在一些容易导致错误的特性。

为什么需要let和const?

let和const的出现解决了var使用过程中的几个痛点:

  • 解决了变量提升导致的混乱:var声明的变量会被提升到其作用域顶部(变量提升),并用undefined初始化,能在定义前访问而不报错(输出undefined),违反直觉。为解决这一问题引入了const和let,因这两者存在暂时性死区(在此区域外访问会抛出错误:ReferenceError)
  • 提供了块级作用域:var没有块级作用域,导致在for循环或if语句中声明的变量会泄漏到外部,而let和const仅在声明他们的代码块(如for循环内或if语句内)有效,提供了更强的封装性。
  • 引入常量:const允许声明一个值不能被重新赋值的常量,有助于提高代码的可维护性和健壮性(防止意外修改)

API与用法

var
  • 作用域:函数作用域或全局作用域。
  • 提升:变量提升,初始化为undefined。
  • 重复声明:允许在同一作用域内重复声明。
  • 可变性:可以重新赋值。
function varExample(){ console.log(a);//输出:undefined(变量提升) var a=10; console.log(a);//输出:10 if(true){ a=20;// 覆盖了函数作用域中的a console.log(a);//输出:20 } console.log(a);//输出:20 }
let
  • 作用域:块级作用域 ({...})。
  • 提升:不提升(存在暂时性死区)。
  • 重复声明:不允许在同一作用域内重复声明。
  • 可变性:可以重新赋值。
function letExample(){ console.log(b);// 输出:ReferenceError: Cannot access 'b' before initialization (TDZ) let b = 10; console.log(b);// 输出:10 if(true){ console.log(b);// 输出:10 let b=20;// 注意:如果这里改为b=20,下面的console就都是20 console.log(b);// 输出:20,在块级作用域内可以被重新赋值 } console.log(b);// 输出:10, }
const
  • 作用域:块级作用域({...})。
  • 提升:不提升(存在暂时性死区)。
  • 重复声明:不允许在同一作用域重复声明。
  • 可变性:不能重新赋值,声明时必须出示话。
function constExample (){ const c=30; console.log(c);// 输出:30 // c=40;//TypeError: Assignment to constant variable. // const c=40;//无法重新声明块范围变量“c”。 // 注意:对于对象或数组,const 保证的是变量绑定的引用不变, // 但对象或数组自身的内容是可变的。 const obj={name:'hello'}; obj.name='你好';// 这是允许的 console.log(obj.name);// 输出:你好 }

关键注意事项:

  1. 暂时性死区:let和const声明的变量,从其作用域开始到声明语句之间是暂时性死区(TDZ)。在此区域内访问变量会抛出ReferenceError。
  2. 全局对象属性:在全局作用域下,使用var声明的变量会成为window(浏览器环境)或(Node.js环境)对象的属性。cont和let不会。
  3. const的不变性:const保证的是变量指向的内存地址(引用)不可变,而不是该地址中的数据不可变。对于引用类型(如对象、数组),其内部属性或元素是可以修改的。
  4. 优先使用const:默认应优先使用const来声明变量,只有当确定变量需要被重新赋值时,才使用let。这能增强代码的可靠性,避免不必要的变量修改。

什么是暂时性死区?

定义:

从块级作用域开始到变量声明语句之间的区域,在此区域内访问变量会抛出ReferenceError

暂时性死区常见陷阱:

即使外层有同名变量,内层的let声明仍会创建新的绑定和 TDZ。

let x = 'outer'; { console.log(x); // ❌ ReferenceError // 不是因为外层有 x,而是本作用域的 let x 声明导致 TDZ let x = 'inner'; }
function foo(x = y, y = 2) { return [x, y]; } foo(); // ❌ ReferenceError: Cannot access 'y' before initialization // 原因:计算 x = y 时,y 还在 TDZ 中
// 正常情况 typeof undeclaredVar; // ✅ "undefined" // TDZ 中 typeof x; // ❌ ReferenceError let x;
为什么需要暂时性死区?
// 没有 TDZ 时(假设): var tmp = true; if (tmp) { console.log(x); // 可能期望访问外层的 x var x = 5; // 实际会变量提升,不会报错但行为混乱 } // 有 TDZ 时: let tmp = true; if (tmp) { console.log(x); // ✅ 明确报错,避免意外行为 let x = 5; // 块级作用域清晰 }

解释一下var 变量提升的本质

结合上下文创建过程,你会知道,其实根本不存在任何的 “提升”,变量一直在原地。所谓的 “提升”,只是变量的创建过程(在上下文创建阶段完成)和真实赋值过程(在上下文执行阶段完成)的不同步带来的一种错觉。执行上下文在不同阶段完成的不同工作,才是 “变量提升 “的本质。

http://www.jsqmd.com/news/622975/

相关文章:

  • window安装milvus
  • Jimeng LoRA多场景落地:短视频团队用LoRA快速生成统一画风分镜草图
  • 在Blender中实现3MF格式的终极导入导出:5分钟快速上手指南
  • 杉德斯玛特卡快速回收方法:使用技巧与回收常见问题解答 - 团团收购物卡回收
  • R语言计算风险价值太慢?5个被90%金融机构忽略的底层优化陷阱(附实测加速8.7倍代码)
  • 从入门到放弃?WPF Chart实时曲线开发的5个常见坑与高效填坑指南
  • AIGlasses OS Pro性能调优实战:跳帧与画面缩放提升FPS技巧
  • kill-doc:你的文档下载终极解决方案,告别繁琐操作只需3步
  • 北航毕业论文LaTeX终极指南:5分钟快速上手的专业排版解决方案
  • TBC2024.1如何通过多源测绘设备数据融合提升工程交付效率
  • Wan2.2-I2V-A14B自动化运维:利用运维脚本实现模型服务监控与弹性伸缩
  • MindOS:你的AI第二大脑知识库
  • 案例分享:nli-distilroberta-base如何助力文本内容审核与逻辑校验
  • 【已解决】Windows10下DGCNN训练中RuntimeError: tensors设备不一致问题的排查与修复
  • C语言笔记6:变量生命周期、指针与数组指针全解析
  • 联合概率数据关联(JPDA)与卡尔曼滤波:多目标跟踪中的精准状态估计
  • 基于MOPGA-NSGA-II 的电动车多目标路径优化研究(考虑路况天气与充电约束)(Matlab代码实现)
  • FaceFusion使用指南:如何配置局域网访问实现多端协同?
  • 别再死记硬背Hive架构图了!从一次SQL查询失败,带你手把手拆解Driver四大组件的工作流程
  • 从零到精通:GraphvizOnline在线流程图工具完全指南
  • 如何用Mermaid Live Editor快速创建专业图表:免费实时编辑完全指南
  • C++基础语法2-模板
  • 如何快速找回加密压缩包的密码:ArchivePasswordTestTool终极指南
  • FPGA数字前端
  • 学会评估模型的拟合状态和泛化能力
  • 密度峰值聚类(DPC)的5个常见误区及改进方案
  • 深度解析:Legacy-iOS-Kit - 终极iOS设备降级与越狱解决方案
  • 如何用10分钟语音打造专业AI变声器:RVC语音转换终极指南
  • WarcraftHelper终极指南:轻松解决魔兽争霸III现代系统兼容性问题
  • NumPy随机数生成函数的多种实现方法