ECMAScript 6 基础
一、变量声明
1.1 var
1.2 let
1.3 const
1.4 暂时性死区
1.5 循环体内的变量
二、字符串的扩展
2.1 字符串方法
2.2 模板字面量
三、函数的扩展
3.1 参数默认值
3.2 剩余参数
3.3 扩展运算符
3.4 箭头函数
四、对象的扩展
4.1 对象字面量
4.2 相等性判断
4.3 属性复制
五、数组的扩展
5.1 创建数组
5.2 数组方法
六、解构
6.1 对象解构
6.2 数组解构
6.3 参数解构
七、Symbol
7.1 创建 Symbol
7.2 使用 Symbol
7.3 共享 Symbol
7.4 检索 Symbol
八、Set 与 Map
8.1 Set
8.2 WeakSet
8.3 Map
8.4 WeakMap
九、迭代器与生成器
9.1 迭代器
9.2 生成器
9.3 for-of 循环
9.4 内置迭代器
十、类
10.1 类
10.2 继承
十一、代理与反射
十二、模块化
12.1 基本导出
12.2 基本导出
12.3 导入路径
12.4 导入导出重命名
12.5 导入导出默认值
12.6 导入再导出
12.7 无绑定导入
一、变量声明
1.1 var
在 JavaScript 语言中,使用 var
关键字声明的变量,无论其实际声明位置在何处,都会被视为声明与所在函数的顶部;如果声明不在函数内,则视为在全局作用域的顶部,这就是所谓的变量提升:
function test(flag) {
if (flag) {
var value = "blue";
console.log(value);
} else {
console.log(value);
}
console.log(value);
}
由于变量提升的影响,以上的代码在效果上与下面的代码等效:
function test(flag) {
// 提升到函数顶部
var value;
if (flag) {
value = "blue";
console.log(value);
} else {
console.log(value);
}
console.log(value);
}
同样,由于变量提升的影响,你在函数外部声明的变量可能会覆盖原有的全局变量:
var RegExp = "Hello!";
console.log(window.RegExp); // Hello!
console.log(window.RegExp === RegExp); // true
为了改变这一影响, ES6 引入了 let
关键字。
1.2 let
let
关键字具有以下作用:
- 使用
let
关键字声明的变量具有块级作用域;
function test(flag) {
if (flag) {
let value = "blue"; // value的作用域被限制在该{}所包裹的代码块中
console.log(value);
} else {
console.log(value); //value在此处不能访问
}
console.log(value); //value在此处不能访问
}
- 禁止重复声明变量:
let value = "blue";
let value = "blue"; // 不被允许,会抛出异常 Identifier 'value' has already been declared
- 在函数体外部声明的变量不会覆盖原有的同名的全局变量,只能将其屏蔽:
let RegExp = "Hello!";
console.log(RegExp); // Hello! 屏蔽原有的全局变量
console.log(window.RegExp === RegExp); // false 但不会将其覆盖
1.3 const
ES6 中新增了 const
关键字,用于声明不可变的常量,它类似于 Java 语言中的 final
关键字,具有如下特性:
- 使用
const
关键字修饰的变量在声明时必须指定初始化的值,并且该变量不可以再被重新赋值; - 使用
const
关键字修饰的变量同样具备块级作用域; - 同样可以禁止重复声明变量;
- 和 Java 语言类似,如果
const
修饰的是对象,此时你仍然可以修改对象的属性:
const author = {
name: "heibai",
};
author.name = "ying"; // 可以修改对象的属性
console.log(author); // 但不可以对 const 修饰的常量进行重新赋值
author = {
name: "heibaiying"
};
1.4 暂时性死区
和 var
关键字不同,使用 let
和 const
关键字声明的变量,在达到声明处之前都是无法访问的:
(function test() {
console.log(typeof value); // ReferenceError: value is not defined
let value = "blue"; // 下面的语句都不会被输出
console.log(value);
})();
在 value 所在的块级作用域中,如果还没有到达 value 声明行,此时的 value 会被存放在称为 “暂时性死区” 的区域中,只有在 value 声明行之后,该值才会被移出 “暂时性死区”。注意,这里强调的是在 value 所在的块级作用域中, 如果不是在 value 所在的块级作用域中,是不会存在暂时性死区:
console.log(typeof value); // undefined
(function test() {
let value = "blue";
console.log(value); // blue
})();
1.5 循环体内的变量
如果在循环体中使用 var
变量,其仍然会被提升到全局,这意味着它可以在循环体外部被使用:
for (var i = 0; i < 10; i++) {
}
console.log(i); // i 在此处仍然可被访问,值为 10,如果使用的是 let 则不会有类似情况
同样的原因,如果在循环体内创建函数,并且函数持有对 i 变量的引用,也会导致同样的问题:
let list = [];
for (var i = 0; i < 10; i++) {
list.push(function () {
console.log(i);
});
}
list.forEach(function (func) {
func();
});
// 输出 10 次 10
如果使用 let
关键字进行修饰,则每一次循环都会创建一个 i 的副本:
let list = [];
for (let i = 0; i < 10; i++) {
list.push(function () {
console.log(i);
});
}
list.forEach(function (func) {
func();
});
// 输出 0 到 9