宣告变量有三种方式:
- var
- let
- const
var 与 let、const 的主要差异在于作用域。
作用域(Scope)
变量可以使用范围的定义,如果超出此范围就会无法使用。
var
作用域:Function(函数)
例如:
function test() {
var x = 10;
}
console.log(x); // 错误信息:Uncaught ReferenceError: x is not defined
但是如果是以下的状况:
if (true) {
var x = 10;
}
console.log(x); // 显示 10
console.log(x) 可以显示是因为变量 x 并不是存在于 function 内(它是存在于 if 条件内),如果我们希望 x 作为暂存的用途,并限制其范围在括号内不要跑出去区块外面,此时有更好的选择就是使用 let。
let
作用域:block(区块)
if (true) {
let x = 10;
}
console.log(x); // 错误信息:Uncaught ReferenceError: x is not defined
使用 let,变量的作用域就可以限制在大括号(区块)内!
此外,使用 var 容易造成所谓的“命名空间污染”,不小心重新命名了已经在使用的变量名称,造成代码运行和维护上的问题,而 let 就相对地好用多了。
例如:
let x = 1; // 作用域:区块外(全域)
if (true) {
let x = 2; // 作用域:区块内
console.log(x); // 显示 2
}
console.log(x); // 显示 1
这两个 x 会被当作完全不同的变量,区块外的 x 值不影响区块内 x 的值,所以不会有命名空间污染的问题,如果将 let 改为 var,此时两个输出都将会是 2!
const
作用域:block(区块)
const 的作用域和 let 是一样的,只是如同 const 的字面含义,它是用来宣告常量(constant)的,不同于 let 是用来宣告变量(variable)。
const x = 10;
x = 20; // 错误信息:Uncaught TypeError: Assignment to constant variable.
如果修改 const 宣告的变量,是会出现错误信息的!
要注意的是如果 const 宣告的是 Object:
const dog = {
name: 'pipi',
color: 'yellow'
}
dog.name = 'lucky';
console.log(dog); // 显示 Object {name: "lucky", color: "yellow"}
此时还是可以修改,如果要禁止此 Object 被修改则要使用 Object.freeze()
这个方法。
const dog = {
name: 'pipi',
color: 'yellow'
}
const myDog = Object.freeze(dog);
myDog.name = 'lucky'
console.log(myDog); // 显示 Object {name: "pipi", color: "yellow"}
虽然我们将 myDog 的属性做了修改,可是此时并没有影响原有的值!
使用及修改全域变量都是非常危险的,善用 let 和 const 则可以避免原本应该属于区块内的变量覆盖区块外(全域)的变量,也可以避免区块内不小心修改到属于区块外(全域)的变量。
建议多使用 let 和 const,至于 var 可以应用在需要在整个系统内多个作用域都必须被存取的情境中使用。
严格说起来 var 并不是用来定义全域变量的,只是有时它宣告的位置刚好会让它具有全域的效果。
而在 ES6 之后的版本也建议不要再继续使用 var 而改用 let。