ES2015+ 备忘清单
快速浏览 ES2015、ES2016、ES2017、ES2018 及以后的 JavaScript 新特性
常用
块范围
Let
``js {2,4}
function fn () {
let x = 0
if (true) {
let x = 1 // 只在这个if`里面
}
}
#### Const```jsconst a = 1
let 是新的 var。 常量(const) 就像 let 一样工作,但不能重新分配。
请参阅:Let 和 const
反引号字符串
插值
const message = `Hello ${name}`
多行字符串
const str = `helloworld`
模板和多行字符串。 请参阅:模板字符串
二进制和八进制文字
let bin = 0b1010010let oct = 0o755
请参阅:二进制和八进制文字
指数运算符
```js {1} const byte = 2 ** 8 // 同: Math.pow(2, 8)
### 新方法#### 新的字符串方法```js"hello".repeat(3)"hello".includes("ll")"hello".startsWith("he")"hello".padStart(8) // " hello""hello".padEnd(8) // "hello ""hello".padEnd(8, '!') // hello!!!"\u1E9B\u0323".normalize("NFC")
新的数字方法
Number.EPSILONNumber.isInteger(Infinity) // falseNumber.isNaN("NaN") // false
新的 Math 方法
Math.acosh(3) // 1.762747174039086Math.hypot(3, 4) // 5Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2
新的 Array 方法
// 返回一个真实的数组Array.from(document.querySelectorAll("*"))// 类似于 new Array(...),但没有特殊的单参数行为Array.of(1, 2, 3)
请参阅: 新方法
类
class Circle extends Shape {
构造函数
```js {1} constructor (radius) { this.radius = radius }
#### 方法```js {1}getArea () {return Math.PI * 2 * this.radius}
调用超类方法
```js {2} expand (n) { return super.expand(n) * Math.PI }
#### 静态方法```js {1}static createFromDiameter(diameter) {return new Circle(diameter / 2)}}
原型的语法糖。 请参阅: 类
Promises
做出承诺
```js {1} new Promise((resolve, reject) => { if (ok) { resolve(result) } else { reject(error) } })
用于异步编程。请参阅:[Promises](https://babeljs.io/learn-es2015/#promises)### 使用 Promises```js {2,3}promise.then((result) => { ··· }).catch((error) => { ··· })
在 finally 中使用 Promise
```js {4} promise .then((result) => { ··· }) .catch((error) => { ··· }) .finally(() => { / 独立于成功/错误的逻辑 / })
当承诺被履行或被拒绝时,处理程序被调用### Promise 函数```jsPromise.all(···)Promise.race(···)Promise.reject(···)Promise.resolve(···)
Async-await
```js {2,3} async function run () { const user = await getUser() const tweets = await getTweets(user) return [user, tweets] }
`async` 函数是使用函数的另一种方式。请参阅:[异步函数](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)解构 Destructuring-------------### 解构赋值#### Arrays```js {1}const [first, last] = ['Nikola', 'Tesla']
Objects
```js {1} let {title, author} = { title: ‘The Silkworm’, author: ‘R. Galbraith’ }
支持匹配数组和对象。请参阅:[解构](https://babeljs.io/learn-es2015/#destructuring)### 默认值```jsconst scores = [22, 33]const [math = 50, sci = 50, arts = 50] = scores
// Result:// math === 22, sci === 33, arts === 50
可以在解构数组或对象时分配默认值
函数参数
``js {1}
function greet({ name, greeting }) {
console.log(${greeting}, ${name}!`)
}
----```jsgreet({ name: 'Larry', greeting: 'Ahoy' })
对象和数组的解构也可以在函数参数中完成
默认值
``js {1}
function greet({ name = 'Rauno' } = {}) {
console.log(Hi ${name}!`);
}
----```jsgreet() // Hi Rauno!greet({ name: 'Larry' }) // Hi Larry!
重新分配键
``js {1}
function printCoordinates({ left: x, top: y }) {
console.log(x: ${x}, y: ${y}`)
}
----```jsprintCoordinates({ left: 25, top: 90 })
此示例将 x 分配给 left 键的值
循环
```js {1} for (let {title, artist} of songs) { ··· }
赋值表达式也在循环中工作### 对象解构```js {1}const { id, ...detail } = song;
使用 rest(...) 运算符单独提取一些键和对象中的剩余键
扩展运算符 Spread
对象扩展
与对象扩展
```js {2} const options = { …defaults, visible: true }
#### 没有对象扩展```jsconst options = Object.assign({}, defaults,{ visible: true })
对象扩展运算符允许您从其他对象构建新对象。 请参阅:对象传播
数组扩展
具有数组扩展
```js {2,3} const users = [ …admins, …editors, ‘rstacruz’ ]
#### 没有数组扩展```jsconst users = admins.concat(editors).concat([ 'rstacruz' ])
扩展运算符允许您以相同的方式构建新数组。 请参阅:扩展运算符
函数 Functions
函数参数
默认参数
``js {1}
function greet (name = 'Jerry') {
returnHello ${name}`
}
#### Rest 参数```js {1}function fn(x, ...y) {// y 是一个数组return x * y.length}
扩展
```js {1} fn(…[1, 2, 3]) // 与 fn(1, 2, 3) 相同
Default(默认), rest, spread(扩展)。请参阅:[函数参数](https://babeljs.io/learn-es2015/#default--rest--spread)### 箭头函数<!--rehype:wrap-class=row-span-3-->#### 箭头函数```js {1}setTimeout(() => {···})
带参数
```js {1} readFile(‘text.txt’, (err, data) => { … })
#### 隐式返回```js {1,4,5,6}arr.map(n => n*2)// 没有花括号 = 隐式返回// 同: arr.map(function (n) { return n*2 })arr.map(n => ({result: n*2}))// 隐式返回对象需要在对象周围加上括号
类似函数,但保留了 this。
请参阅:箭头函数
参数设置默认值
function log(x, y = 'World') {console.log(x, y);}log('Hello') // Hello Worldlog('Hello', 'China') // Hello Chinalog('Hello', '') // Hello
与解构赋值默认值结合使用
function foo({x, y = 5} = {}) {console.log(x, y);}foo() // undefined 5
name 属性
function foo() {}foo.name // "foo"
Objects
速记语法
module.exports = { hello, bye }
同下:
module.exports = {hello: hello, bye: bye}
请参阅:对象字面量增强
方法
```js {2} const App = { start () { console.log(‘running’) } } // 同: App = { start: function () {···} }
请参阅:[对象文字增强](https://babeljs.io/learn-es2015/#enhanced-object-literals)### Getters and setters```js {2,5}const App = {get closed () {return this.status === 'closed'},set closed (value) {this.status = value ? 'closed' : 'open'}}
请参阅:对象字面量增强
计算属性名称
```js {3} let event = ‘click’ let handlers = {
} // 同: handlers = { ‘onclick’: true }
请参阅:[对象字面量增强](https://babeljs.io/learn-es2015/#enhanced-object-literals)### 提取值```js {3,5}const fatherJS = { age: 57, name: "张三" }Object.values(fatherJS)// [57, "张三"]Object.entries(fatherJS)// [["age", 57], ["name", "张三"]]
Modules 模块
Imports 导入
import 'helpers'// 又名: require('···')
import Express from 'express'// 又名: const Express = require('···').default || require('···')
import { indent } from 'helpers'// 又名: const indent = require('···').indent
import * as Helpers from 'helpers'// 又名: const Helpers = require('···')
import { indentSpaces as indent } from 'helpers'// 又名: const indent = require('···').indentSpaces
import 是新的 require()。
请参阅:Module imports
Exports 导出
export default function () { ··· }// 又名: module.exports.default = ···
export function mymethod () { ··· }// 又名: module.exports.mymethod = ···
export const pi = 3.14159// 又名: module.exports.pi = ···
const firstName = 'Michael';const lastName = 'Jackson';const year = 1958;export { firstName, lastName, year };
export * from "lib/math";
export 是新的module.exports。
请参阅:Module exports
as 关键字重命名
```js {2,8,12-14} import { lastName as surname // 导入重命名 } from ‘./profile.js’;
function v1() { … } function v2() { … }
export { v1 as default }; // 等同于 export default v1;
export { v1 as streamV1, // 导出重命名 v2 as streamV2, // 导出重命名 v2 as streamLatestVersion // 导出重命名 };
### 动态加载模块```jsbutton.addEventListener('click', event => {import('./dialogBox.js').then(dialogBox => {dialogBox.open();}).catch(error => {/* Error handling */})});
ES2020提案 引入 import() 函数
import() 允许模块路径动态生成
const main = document.querySelector('main')import(`./modules/${someVariable}.js`).then(module => {module.loadPageInto(main);}).catch(err => {main.textContent = err.message;});
import.meta
ES2020 为 import 命令添加了一个元属性 import.meta,返回当前模块的元信息
new URL('data.txt', import.meta.url)
Node.js 环境中,import.meta.url返回的总是本地路径,即 file:URL 协议的字符串,比如 file:///home/user/foo.js
Generators
Generator 函数
function* idMaker () {let id = 0while (true) { yield id++ }}
let gen = idMaker()gen.next().value // → 0gen.next().value // → 1gen.next().value // → 2
情况很复杂。 请参阅:Generators
For..of + 迭代器(iterator)
let fibonacci = {[Symbol.iterator]() {let pre = 0, cur = 1;return {next() {[pre, cur] = [cur, pre + cur];return { done: false, value: cur }}}}}for (var n of fibonacci) {// 在 1000 处截断序列if (n > 1000) break;console.log(n);}
用于迭代生成器和数组。 请参阅:For..of iteration
与 Iterator 接口的关系
var gen = {};gen[Symbol.iterator] = function* () {yield 1;yield 2;yield 3;};[...gen] // => [1, 2, 3]
Generator 函数赋值给 Symbol.iterator 属性,从而使得 gen 对象具有了 Iterator 接口,可以被 ... 运算符遍历了
Symbol.iterator 属性
function* gen() { /* some code */ }var g = gen();g[Symbol.iterator]() === g // true
gen 是一个 Generator 函数,调用它会生成一个遍历器对象g。它的 Symbol.iterator 属性,也是一个遍历器对象生成函数,执行后返回它自己
另见
- Learn ES2015 (babeljs.io)
- ECMAScript 6 功能概述 (github.com)
- ECMAScript 6 入门教程 (阮一峰) (ruanyifeng.com)
