通常看作js的标准化规范,实际上js是ES的扩展语言,ES只提供了最基本的语法,但仅停留在语言层面。
ES2015(ES6)
最新ES标准的代表版本。
- 相比于ES5.1的变化较大;
- 自此,标准命名规则发生变化;
- ES6也可以泛指2015之后的所有新标准,因此需要区别泛指和特指。
let与块级作用域
- ES2015新增了块级作用域,在此之前只有全局作用域和函数作用域;
-
for
循环有两层嵌套的作用域,循环体内的变量是内层独立的作用域,不会被for
循环本身的作用域影响; -
let
没有变量提升。
const
声明后不允许被修改(不能重新指向一个新的内存地址,并非不能修改恒量中的属性成员)。
⚠️最佳实践:不用var
,主用const
,配合let
。
解构
- 数组的解构
- 位置一一对应,逗号不可省略;
- 剩余元素用
...res
,只能放在解构的最后位置; - 超出部分为
undefined
; - 可以用
=
设置默认值。
- 对象的解构
- 使用键值对应对象中的属性名;
- 可以用
:
重命名。
模范字符串
- 支持换行;
- 使用
${}
嵌入变量; - 在模板字符串之前添加一个标签,这个标签实际上是一个特殊的函数,意味调用这个函数,能够对模板字符串进行加工,实现文本的多元化、中英文翻译、检查不安全字符、实现小型等模板引擎等。
字符串的扩展方法:
- includes()
- startsWith()
- endsWith
参数默认值
直接用=
后面接默认值,带有默认值的参数需要放到最后。
...操作符
- 接收剩余参数,放在形参的最后;
- 展开数组,简化操作。
const arr = ['foo', 'bar', 'baz']
console.log.apply(console, arr)
console.log(...arr)
箭头函数与this
箭头函数中没有this
的机制,不会改变箭头函数的指向。
const person = {
name: 'tom',
// sayHi: function () {
// console.log(`hi, my name is ${this.name}`)
// }
sayHi: () => {
console.log(`hi, my name is ${this.name}`) // undefined
},
sayHiAsync: function () {
// const _this = this
// setTimeout(function () {
// console.log(_this.name)
// }, 1000)
console.log(this)
setTimeout(() => {
// console.log(this.name)
console.log(this)
}, 1000)
}
}
person.sayHiAsync()
对象字面量的增强
- 变量名如果和属性名相同,可以省略冒号;
- 给对象添加函数,可以省略冒号和function;
- 添加计算属性名,在[]内部可以添加任意表达式作为这个对象的属性名。
对象扩展方法
- Object.assign
将多个源对象中的属性复制到一个目标对象中。
- Object.is
可以区分+0
和-0
,NaN
也等于NaN
。
Proxy(代理对象)
// Proxy 对象
const person = {
name: 'zce',
age: 20
}
const personProxy = new Proxy(person, {
// 监视属性读取
get(target, property) {
return property in target ? target[property] : 'default'
},
// 监视属性设置
set(target, property, value) {
if (property === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError(`${value} is not an int`)
}
}
target[property] = value
}
})
- 对比Object.defineProperty()
- defineProperty只能监视属性的读写,Proxy能监视更多的对象操作;
- Proxy更好的支持数组对象的监视;
- Proxy是以非侵入的方式监管了对象的读写。
Reflect
统一提供一套用于操作对象的API。
Reflect属于一个静态类,内部封装了一系列对对象的底层操作。Reflect成员方法就是Proxy处理对象的默认实现。
Promise
一种更优的异步编程解决方案,解决了传统异步编程中回调函数嵌套过深的问题。
class类
- 静态方法
静态方法是挂载到类型上面的,所以在静态方法内,this就不会指向某个实例对象,而是当前的类型
新增的数据结构
-
Set(集合)
内部不允许重复,常用于数组去重。- .size():返回集合长度
- .add():向集合中添加元素
- .has():判断集合中是否有某值
- .delete():删除集合中的值
- .clear():清空集合
-
Map(键值对集合)
- 与对象的区别,可以使用任意类型的值作为对象的键
-
Symbol
表示一个独一无二的值。
- 可以作为对象的键,可用于避免对象属性名重复的问题;
- 可以模拟实现对象的私有成员;
- .for()可以接收一个字符串,如果传参非字符串也会被转换成字符串,维护的是字符串和Symbol的对应关系;
- .toStringTag是一个内置的Symbol常量;
- Object.getOwnPropertySymbols获取到对象中类型为Symbol的属性名。
for ... of循环
以后会作为遍历所有数据结构的统一方式。
- 可以使用
break
关键字随时终止循环; - 实现可迭代接口是for ... of的前提。
可迭代接口
// 实现可迭代接口Iterable
const obj = {
store: ['foo', 'bar', 'baz'],
[Symbol.iterator]: function () {
const self = this
let index = 0
return {
next: function () {
const result = {
value: self.store[index],
done: index >= self.store.length
}
index++
return result
}
}
}
}
- 迭代器设计模式:对外提供一个统一的接口,让外部无需关心内部的结构。
generator
生成器函数会返回一个生成器对象,调用这个对象的next方法可以让这个函数开始执行,一旦遇到yield,函数执行就会被暂停,同时yield后面的值会作为next的结果返回。
ES2016概述
- 数组新增includes方法;
- 新增指数运算符
**
。
ES2017概述
- Object.values():返回对象中所有的值;
- Object.entries():返回对象中所有的键值对;
- Object.getOwnPropertyDescriptors():获取对象中的完整描述信息;
- String.padStart()/String.padEnd():用给定的字符串填充目标字符串的开始或结束位置知道这个字符串达到制定长度为止;
- 在函数参数中添加尾逗号。