在 ES6 中,let 和 const 成为了新的声明变量的方式,相比于 var,它们有更严格的作用域规则和更好的代码可读性。但是,使用不当也可能会导致一些问题,本文将详细介绍如何在 ES6 中正确使用 let 和 const。
let
let 声明的变量有块级作用域,只在当前代码块内有效。使用 let 可以避免变量提升和全局变量污染。
块级作用域
在 ES5 中,由于没有块级作用域,很容易出现一些奇怪的问题,比如:
for (var i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, 1000); }
预期输出结果是 0 到 4,但实际上输出的是 5 个 5。原因是 setTimeout 中的函数是异步执行的,当它执行时,for 循环已经结束,i 的值为 5。
使用 let 可以解决这个问题:
for (let i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, 1000); }
输出结果为 0 到 4。
变量提升
在 ES5 中,使用 var 声明变量时,变量会被提升到函数作用域或全局作用域的顶部。这可能会导致一些奇怪的问题,比如:
console.log(a); // undefined var a = 1;
使用 let 可以避免变量提升:
console.log(a); // ReferenceError: a is not defined let a = 1;
全局变量污染
在 ES5 中,使用 var 声明变量时,变量会成为全局变量,容易造成变量污染。比如:
var a = 1; function foo() { console.log(a); var a = 2; } foo(); // undefined
使用 let 可以避免全局变量污染:
let a = 1; function foo() { console.log(a); let a = 2; } foo(); // 1
循环中使用 let
在循环中使用 let 可以避免上面提到的异步问题:
for (let i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, 1000); }
输出结果为 0 到 4。
const
const 声明的变量也有块级作用域,它声明的变量是常量,不能重新赋值。使用 const 可以避免不小心修改变量的问题。
常量
使用 const 声明的变量是常量,不能重新赋值:
const a = 1; a = 2; // TypeError: Assignment to constant variable.
块级作用域
const 声明的变量也有块级作用域:
if (true) { const a = 1; } console.log(a); // ReferenceError: a is not defined
对象和数组
使用 const 声明的变量指向的是一个对象或数组的地址,地址不能修改,但是对象或数组本身可以修改:
const obj = { a: 1 }; obj.a = 2; console.log(obj); // { a: 2 }
const arr = [1, 2, 3]; arr.push(4); console.log(arr); // [1, 2, 3, 4]
如果要禁止修改对象或数组本身,可以使用 Object.freeze 方法:
const obj = Object.freeze({ a: 1 }); obj.a = 2; // TypeError: Cannot assign to read only property 'a' of object '#<Object>'
总结
使用 let 和 const 声明变量可以避免很多问题,但是需要注意作用域和常量的特性。在循环中使用 let 可以避免异步问题,在需要声明常量的地方使用 const 可以避免不小心修改变量的问题。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/657db841d2f5e1655d891284