在 TypeScript(与现代 JavaScript 一样),可以使用 let、const 和 var 声明变量,它们之间有重要的区别:
示例:
if (true) { let a = 10; const b = 20; var c = 30; } console.log(c); // 30 — 在块外可见! console.log(a); // 错误:a is not defined console.log(b); // 错误:b is not defined
典型场景:
const — 用于不应改变的值(常量、配置、函数引用)。let — 用于在执行过程中会改变的值(计数器、循环中的变量)。var — 不推荐使用,仅用于支持旧代码。
const能否使对象完全不可变?解释一下,给出示例。
回答: 不,const 仅防止改变引用本身,但对子对象属性没有保护!
const obj = { x: 1 }; obj.x = 2; // 这是允许的! obj = { x: 3 }; // 错误:赋值新引用
要实现完全不可变性,使用 Object.freeze:
const frozen = Object.freeze({ x: 1 }); frozen.x = 2; // 在严格模式下会报错,但编译器并不总是会警告!
故事
在将一个大型前端项目迁移到 TypeScript 的过程中,开发人员大规模地将 var 替换为 let,而没有考虑到作用域现在变为块级。这导致某些 for 循环中的计数器在循环外不可用,并且在逻辑中出现了意外错误:代码在尝试在循环结束后访问计数器时停止工作。
故事
开发人员通过 const 声明了一个常量以存储配置对象,以为属性不会被更改。后来在运行时,程序的其他地方更改了属性:这引发了数据处理中的难以察觉的错误,因为外部代码“意外”更改了所有用户的全局设置。
故事
在项目中,同时使用 let、const 和 var 而没有明确的政策。一个组件在功能内重新声明了 var 变量,而另一个地方则期望该变量通过 let 声明,因此在块外不可见。结果:变量重叠、内部逻辑故障和难以调试的变量生命周期问题。