ES5 变量
ES6 变量 ( 常量 )
- 使用
let
关键字定义。let
不会进行变量提升,必须先定义再使用- 暂时性死区 (TDZ):变量没有
let
之前的区域。在暂时性死区内,该变量都不能使用
- 暂时性死区 (TDZ):变量没有
- 在同一作用域内,变量可以重复用
var
定义;但不能重复用let
定义 - ES5 只有全局作用域和函数作用域;ES6 中的是块级作用域
{}
…
如果使用 var
实现事件的批量绑定,会出问题:
<input type="button" value="a" />
<input type="button" value="b" />
<input type="button" value="c" />
<script>
let aInput = document.querySelectorAll("input");
for (var i = 0; i < aInput.length; i++) {
aInput[i].onclick = function () {
console.log(i); // 3 3 3
}
}
</script>
这时可以使用 let
实现事件的批量绑定:
let aInput = document.querySelectorAll("input");
for (let i = 0; i < aInput.length; i++) { // 块级作用域
aInput[i].onclick = function () { // i 与事件对应
console.log(i); // 0 1 2
}
}
注意
:对于 for
循环,{}
内的变量会覆盖 ()
内的同名变量
for (let i = 0; i < 10; i++) {
let i = 10;
console.log(i); // 10 个 10
}
但其实它们应该是在同一个作用域内,不能被重复定义才对的
const
let
的特性const
都有const
定义的是常量,常量必须在定义时初始化,且不能修改常量值
const NUM = 10;
NUM = 20; // TypeError
注意:对于引用类型的数据,是操作其内存地址:
const NUM = [10];
NUM.push(20);
console.log(NUM); // [10, 20]
在此过程中,内存地址没有发生改变,所以可以改变数组内容
如果不想被修改引用类型数据的内容,可以使用 Object.freeze()
冻结常量
const ARR = Object.freeze(["apple", "banana"]);
ARR.push("orange"); // Uncaught TypeError: Cannot add property 2, object is not extensible
全局变量与顶层对象
顶层对象:浏览器环境内,指的是 window
对象;在 Node 中,指的是 global
对象
ES5 之中,全局变量就是顶层对象的属性
var a = 1;
console.log(window.a); // 1
ES6 引入的 let
、const
和 class
声明的全局变量,不再是顶层对象的属性:
let a = 1;
console.log(window.a) // undefined