被 var 坑惨了?ES6 的 let 和 const 如何拯救你的 JS 代码

177 阅读4分钟

前言

在 JavaScript 的编程世界里,无数开发者都曾被var“坑” 得苦不堪言。变量提升带来的逻辑混乱、缺乏块级作用域导致的变量泄露,这些问题在项目开发中如同隐藏的地雷,稍不注意就会引发难以调试的 bug。而 ES6 引入的let和const,就像救星一般,彻底改变了这一局面,为 JavaScript 开发者带来了全新的变量声明体验。

被 “误解” 的 var:ES5 时代的变量声明困境

在 ES5 时期,var是 JavaScript 中唯一的变量声明关键字。它的设计初衷是为了满足当时简单的页面交互需求,然而随着 JavaScript 应用场景的不断拓展,var的缺陷逐渐暴露无遗。​

变量提升

最令人头疼的便是变量提升特性。var声明的变量会被提升到作用域的顶部,这就导致代码的执行顺序和书写顺序不一致,极大地影响了代码的可读性和可维护性。例如:

console.log(a); // undefined​
var a = 10;

从代码的书写顺序来看,在打印 a 时,a 还未声明赋值,理应报错。但由于变量提升,var a 被提前到作用域顶部,此时 a 处于声明但未赋值的状态,所以打印结果为 undefined。这种不符合直觉的行为,常常让开发者在排查问题时浪费大量时间。

缺乏 块级作用域

var 缺乏块级作用域也是一大弊端。在for循环、if语句等代码块中,使用var声明的变量会 “逃逸” 出块级作用域,成为函数作用域或全局作用域内的变量。例如:

for (var i = 0; i < 5; i++) {
    // do something
}
console.log(i); // 5

循环结束后,i 仍然可以在外部访问,这在复杂的项目中很容易引发命名冲突,导致难以预料的错误。而且,当多个for循环使用相同的变量名时,也会出现变量值被意外修改的情况。

小结

问题缺陷
变量提升代码可读性和维护性差
缺乏块级作用域变量泄露,容易引发命名冲突

ES6 的变革:let 和 const 的登场

ES6 的到来,为 JavaScript 的变量声明带来了革命性的变化,letconst 的引入,完美地解决了var存在的问题。​

let

let具有块级作用域,它声明的变量仅在当前代码块内有效。这意味着在for循环、if语句等块中使用let声明的变量,不会影响到外部作用域。同样是for循环的例子,使用let就会有不同的表现:

for (let i = 0; i < 5; i++) {​
    // do something​
}​
console.log(i); // ReferenceError: i is not defined

循环结束后,i 超出了作用域范围,无法再被访问,这样就避免了变量泄露和命名冲突的问题,使得代码的逻辑更加清晰可控。

const

const则用于声明常量,它同样具有块级作用域。与let不同的是,const声明的变量必须在声明时立即赋值,并且赋值后不能再被重新赋值(对于简单数据类型)。例如:

const PI = 3.1415926;​
PI = 3.14; // TypeError: Assignment to constant variable.

对于const声明的对象(复杂数据类型),虽然对象本身不能被重新赋值,但对象内部的属性是可以修改的:

const person = { name: 'Alice' };​
person.name = 'Bob'; // 合法操作,修改对象内部属性​
person = { name: 'Charlie' }; // TypeError: Assignment to constant variable.

这与简单数据类型与复杂数据类型声明变量分配内存方式的不同有关,下篇文章会讲。

const的存在,让开发者可以更明确地定义那些不应该被修改的值,增强了代码的健壮性和可维护性。

小结

优点
let避免了变量泄露和命名冲突的问题,代码的逻辑清晰可控
const增强代码的健壮性和可维护性

从 var 到 let/const:迈向企业级开发的关键一步

letconst的出现,不仅仅是变量声明方式的改变,更是 JavaScript 迈向企业级开发语言的重要标志。在大型项目中,代码的可读性、可维护性和安全性至关重要,而var带来的诸多问题严重制约了 JavaScript 在企业级开发中的应用。​

letconst通过引入块级作用域常量声明,规范了变量的使用方式,使得代码的逻辑更加清晰,减少了潜在的 bug。同时,它们不会像var那样将变量挂载到全局对象上,避免了全局变量污染,让代码的模块化封装性更好。​

对于每一位 JavaScript 开发者来说,熟练掌握letconst的特性与使用场景,是进阶企业级开发的必经之路。随着 JavaScript 生态的不断发展,这些基础特性也将持续为开发者们打造更优质的开发体验,助力开发者们构建出更加健壮、高效的应用程序。​