intro
之前一直使用var
声明变量(不使用关键字定义的变量xxx
,实为全局变量window.xxx
)。
ES6中新增了两个用于声明变量的关键字:let
const
let
声明的变量只在let
所在的代码块内有效(块级作用域
)。
const
声明只读的常量(也是块级作用域)。
以下先对var
与let
进行对比。而后是const。
var
与let
- 作用域
var
是全局范围有效。
let
是代码块内有效。
最简单的,for循环的递增变量用不同关键字var
和let
声明后,在for循环之后变量是否继续存在|有效?
for (var i = 0; i < 10; i++) {}
console.log(i); // 10
for (let j = 0; j < 5; j++) {}
console.log(j); // Uncaught ReferenceError: j is not defined
- 变量提升
hoisting
用var
声明变量存在变量提升hoisting
。
不过用let
声明变量不存在变量提升。
变量提升:变量是否可以先使用,后用关键字声明。
yes = "sure";
console.log(yes); // sure
var yes;
no = "NO";
console.log(no); // Uncaught ReferenceError: no is not defined
let no;
- 多次声明
使用var
可以重复声明同一个标识符。
但使用let
声明变量,一个标识符只能声明一次,不能重复声明。
var a = 123;
var a = "asd";
let b = 456;
// 只要是之前已经用关键字声明过的变量|标识符,不能用let再次声明。否则报错。
let b = true; // 变量b之前用let生命果,用let再次声明
let a = "哈哈哈"; // 变量a之前用var声明过,用let再次声明
// Uncaught SyntaxError: Identifier 'b' has already been declared
暂时性死区
暂时性死区
:块的开始
->块中用const声明变量的位置
这段空间内的代码。
var PI = "pai";
if (true) {
try {
console.log(PI); // 报错:ReferenceError: PI is not defined
} catch (e) {
console.log(e);
}
let PI = "3.14"; // 此处如果用var声明,则之前使用PI不会报错。
console.log(PI); // 3.14
}
console.log(PI); // "pai"
ES6明确规定,代码块(code block)内如果存在let或const,代码块会对这些命令声明的变量从块的开始
就形成一个作用域。
在代码块内,在声明变量PI之前使用它会报错。
const
const
与let
大致相似,都是块级作用域
,不存在变量提升
,不可重复声明变量
唯一不同的是:const
声明的是常量
,只读
。而let
声明的是可以读写的变量。
用const
声明常量,必须:
- 在声明时初始化变量的值。
- 不能重写值(只能读取)。
// const aaa; // Uncaught SyntaxError: Missing initializer in const declaration
const aaa = 123;
console.log(aaa);
aaa = "hhh"; // Uncaught TypeError: Assignment to constant variable.
关于const
,其实只是保证其声明的变量保存的值
不可二次修改。
- 简单类型: 变量值不可改变。
- 引用类型: 引用值(对象的地址)不可改变。即保证指针(指向的内存地址)的固定。
// 数组对象
const arr = [1,2,3];
arr[0] = "hhh";
console.log(arr); // (3) ["hhh", 2, 3]
// object对象
const obj = {
name: "JT",
age: 22
}
obj.name = "JT666";
console.log(obj); // {name: "JT666", age: 22}