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

JavaScript变量宣言三剑客:var、let、const的奇幻冒险

引言:JavaScript的进化史

从前从前,在编程语言的王国里,有一位名叫JavaScript的小伙子。1995年他出生时,只有var这一种变量声明方式。那时的他天真烂漫,行为随性,直到2015年ES6标准的到来,才为他带来了letconst两位严谨的伙伴,从此开启了JavaScript的"成人礼"。

第一章:老大哥var的"任性人生"

1.1 var的"越狱"行为

function prison() {var prisoner = "I'm here!";if (true) {var prisoner = "I escaped!"; // 同一个囚犯轻松越狱}console.log(prisoner); // "I escaped!" 
}

var就像个不守规矩的魔术师,它无视代码块的边界(块级作用域),在任何地方都能重新声明自己。这种"变量提升"(hoisting)的特性常常让新手开发者抓狂:

console.log(magician); // undefined 而不是报错!
var magician = "Houdini";

1.2 var的"派对狂欢"问题

在循环中使用var就像举办一场失控的派对:

for (var i = 0; i < 3; i++) {setTimeout(() => console.log(i), 100); // 3, 3, 3
}

所有客人(回调函数)看到的都是派对结束后的狼藉(最终值),而不是派对进行时的每个精彩瞬间。

第二章:let的"纪律部队"

2.1 let的"军事化管理"

ES6派来的"纪律委员"let解决了var的所有毛病:

let soldier = "at attention";
let soldier = "at ease"; // SyntaxError: 已经声明过啦!{let recruit = "in training";
}
console.log(recruit); // ReferenceError: 新兵不得擅自离营!

2.2 let的"时间胶囊"效应

在循环中使用let,每个迭代都会创建一个新的词法环境,就像给每个客人发了一个专属时间胶囊:

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

2.3 暂时性死区(TDZ)

let有个特别的安保措施——暂时性死区(Temporal Dead Zone):

console.log(agent); // ReferenceError: 特工身份尚未解密!
let agent = "007";

第三章:const的"终极防线"

3.1 const的"不可变宣言"

const就像军事基地的警告标志:

const MISSILE_SILO = "Danger Zone";
MISSILE_SILO = "Safe Zone"; // TypeError: 核按钮岂能随便按!

行业惯例:const常量全大写,像警示牌一样醒目。

3.2 const的"变形记"

但const有个神奇的特性——对于对象和数组,它锁定的只是"容器",而不是"内容物":

const LAB_SPECIMEN = {species: "werewolf"
};
LAB_SPECIMEN.species = "vampire"; // 完全合法!
LAB_SPECIMEN = {}; // TypeError: 容器不可更换!

3.3 冻结对象

想要真正不可变?可以使用Object.freeze

const HERO = Object.freeze({name: "Superman"
});
HERO.name = "Batman"; // 静默失败或在严格模式下报错

第四章:作用域大逃杀

4.1 作用域层级

JavaScript的作用域就像俄罗斯套娃:

  • 全局作用域:window/global这个大套娃
  • 函数作用域:var认识的中号套娃
  • 块级作用域:let/const认识的迷你套娃
const WORLD = "Earth"; // 全球通告function continent() {var country = "China"; // 全国通告if (true) {let city = "Beijing"; // 本市通告}
}

4.2 作用域链的"寻宝游戏"

当JavaScript查找变量时,它会像玩寻宝游戏一样层层向上:

const TREASURE = "gold"; // 第三层function pirateShip() {var TREASURE = "silver"; // 第二层if (true) {let TREASURE = "bronze"; // 第一层console.log(TREASURE); // "bronze"}
}

第五章:现代JavaScript开发指南

5.1 变量声明新规范

  1. 默认使用const:除非需要重新赋值
  2. 需要重新赋值时用let:如循环计数器
  3. 避免使用var:除非维护老旧代码
  4. 命名约定
    • CONSTANTS_IN_UPPERCASE
    • camelCaseForVariables
    • PascalCaseForConstructors

5.2 常见陷阱警示牌

🚧 const不保证对象内容不可变!
🚧 let在同一个作用域内不可重复声明!
🚧 var会穿透if/for等块级作用域!
🚧 未声明的变量会自动成为全局变量(严格模式禁止)!

第六章:幕后原理探秘

6.1 执行上下文的秘密

JavaScript引擎处理变量声明分为三个阶段:

  1. 创建阶段
    • var:初始化为undefined
    • let/const:未初始化(TDZ)
  2. 执行阶段
    • 变量赋值
    • const必须立即赋值

6.2 词法环境的结构

每个执行上下文都有一个关联的词法环境:

LexicalEnvironment
外部环境引用
环境记录
声明式记录
对象式记录

结语:选择正确的工具

就像超级英雄各有专长:

  • var:像死侍,打破常规但难以控制
  • let:像美国队长,纪律严明但灵活
  • const:像钢铁侠的战甲,坚固可靠但有特殊机制

在现代JavaScript开发中,我们应该:默认用const,需要重新赋值用let,永远不要用var(除非你在写1995年的复古代码)。

记住:伟大的代码能力伴随着重大的责任——选择正确的变量声明方式,让你的代码既安全又富有表现力!

http://www.xdnf.cn/news/9442.html

相关文章:

  • 覆盖索引详解:原理、优势与面试要点
  • 循环神经网络(RNN):原理、架构与实战
  • 第1章 计算机系统知识
  • 32. 自动化测试开发之建立mysql和oracle数据库连接池
  • 训练自己的yolo模型,并部署到rk3588上
  • 微元法求解弧长与侧面积
  • 哪些情况索引会失效?
  • ubuntu 24 下使用pip 时碰到Externally Managed Environment Error的解决办法
  • Oracle迁移到瀚高之后,空值问题处理(APP)
  • 数据库相关问题
  • 什么是车间 6S 管理,如何实现人、事、物有序可控
  • [yolov11改进系列]基于yolov11引入全维度动态卷积ODConv的python源码+训练源码
  • QML常用窗口和菜单
  • 深入理解Modbus通信中的延迟机制
  • “相关分析”
  • UE5 蓝图,隐藏一个Actor,同时隐藏它的所有子物体
  • Rust 开发的一些GUI库
  • 如何在 Windows 和 Mac 上擦拭和清洁希捷外置硬盘
  • cf1703G
  • VR 技术与病毒分离鉴定:一场奇妙的邂逅​
  • vue3 getcurrentinstance 用法
  • 聊聊5G RedCap与eRedCap
  • 网络安全方向在校生有哪些证书适合考取?
  • 关于Java内存溢出文件OOM工具JProfiler的使用(示例)
  • 详解srs流媒体服务器的集群
  • 第五期书生大模型实战营——L0G1
  • Python打卡训练营打卡记录day38
  • CentOS 7.0重置root密码
  • Oracle OCP认证考试考点详解083系列16
  • 函数到底有多少细节?