这是用户在 2024-6-13 9:44 为 https://babeljs.io/docs/learn 保存的双语快照页面,由 沉浸式翻译 提供双语支持。了解如何保存?
Skip to main content
跳至主要内容

Learn ES2015

es6features

This document was originally taken from Luke Hoban's excellent es6features repo. Go give it a star on GitHub!
本文档最初来自 Luke Hoban 出色的 es6features repo。请在 GitHub 上给它点赞!

REPL

Be sure to try these features out in the online REPL.
请务必在在线 REPL 中试用这些功能。

Introduction 导言

ECMAScript 2015 is an ECMAScript standard that was ratified in June 2015.
ECMAScript 2015 是 ECMAScript 标准,于 2015 年 6 月获得批准。

ES2015 is a significant update to the language, and the first major update to the language since ES5 was standardized in 2009. Implementation of these features in major JavaScript engines is underway now.
ES2015 是该语言的重大更新,也是自 2009 年 ES5 标准化以来的首次重大更新。目前,这些功能正在主要 JavaScript 引擎中实施。

See the ES2015 standard for full specification of the ECMAScript 2015 language.
有关 ECMAScript 2015 语言的完整规范,请参见 ES2015 标准。

ECMAScript 2015 Features
ECMAScript 2015 功能

Arrows and Lexical This
箭头和词法

Arrows are a function shorthand using the => syntax. They are syntactically similar to the related feature in C#, Java 8 and CoffeeScript. They support both expression and statement bodies. Unlike functions, arrows share the same lexical this as their surrounding code. If an arrow is inside another function, it shares the "arguments" variable of its parent function.
箭头是一种使用 => 语法的函数速记。它们在语法上类似于 C#、Java 8 和 CoffeeScript 中的相关功能。它们同时支持表达式和语句体。与函数不同,箭头与其周围的代码共享相同的词法 this 。如果箭头位于另一个函数内部,则它共享其父函数的 "arguments "变量。

JavaScript
// Expression bodies
var odds = evens.map(v => v + 1);
var nums = evens.map((v, i) => v + i);

// Statement bodies
nums.forEach(v => {
if (v % 5 === 0)
fives.push(v);
});

// Lexical this
var bob = {
_name: "Bob",
_friends: [],
printFriends() {
this._friends.forEach(f =>
console.log(this._name + " knows " + f));
}
};

// Lexical arguments
function square() {
let example = () => {
let numbers = [];
for (let number of arguments) {
numbers.push(number * number);
}

return numbers;
};

return example();
}

square(2, 4, 7.5, 8, 11.5, 21); // returns: [4, 16, 56.25, 64, 132.25, 441]

Classes 班级

ES2015 classes are syntactic sugar over the prototype-based OO pattern. Having a single convenient declarative form makes class patterns easier to use, and encourages interoperability. Classes support prototype-based inheritance, super calls, instance and static methods and constructors.
ES2015 类是基于原型的 OO 模式的语法糖。有了单一方便的声明形式,类模式更易于使用,并鼓励互操作性。类支持基于原型的继承、超级调用、实例和静态方法以及构造函数。

JavaScript
class SkinnedMesh extends THREE.Mesh {
constructor(geometry, materials) {
super(geometry, materials);

this.idMatrix = SkinnedMesh.defaultMatrix();
this.bones = [];
this.boneMatrices = [];
//...
}
update(camera) {
//...
super.update();
}
static defaultMatrix() {
return new THREE.Matrix4();
}
}

Enhanced Object Literals
增强对象字面意义

Object literals are extended to support setting the prototype at construction, shorthand for foo: foo assignments, defining methods and making super calls. Together, these also bring object literals and class declarations closer together, and let object-based design benefit from some of the same conveniences.
对对象字面进行了扩展,以支持在构造时设置原型、速记 foo: foo 赋值、定义方法和进行超级调用。这些扩展使对象字面量和类声明更加接近,并使基于对象的设计受益于一些相同的便利。

JavaScript
var obj = {
// Sets the prototype. "__proto__" or '__proto__' would also work.
__proto__: theProtoObj,
// Computed property name does not set prototype or trigger early error for
// duplicate __proto__ properties.
['__proto__']: somethingElse,
// Shorthand for ‘handler: handler’
handler,
// Methods
toString() {
// Super calls
return "d " + super.toString();
},
// Computed (dynamic) property names
[ "prop_" + (() => 42)() ]: 42
};
caution 注意

The proto property requires native support, and was deprecated in previous ECMAScript versions. Most engines now support the property, but some do not. Also, note that only web browsers are required to implement it, as it's in Annex B. It is available in Node.
proto 属性需要本地支持,在以前的 ECMAScript 版本中已被弃用。现在大多数引擎都支持该属性,但也有一些引擎不支持。此外,需要注意的是,只有网络浏览器需要实现该属性,因为它在附件 B 中。

Template Strings 模板字符串

Template strings provide syntactic sugar for constructing strings. This is similar to string interpolation features in Perl, Python and more. Optionally, a tag can be added to allow the string construction to be customized, avoiding injection attacks or constructing higher level data structures from string contents.
模板字符串为构造字符串提供了语法糖。这与 Perl、Python 等语言中的字符串插值功能类似。可选择添加一个标签,以便自定义字符串的构造,避免注入攻击或从字符串内容构造更高级别的数据结构。

JavaScript
// Basic literal string creation
`This is a pretty little template string.`

// Multiline strings
`In ES5 this is
not legal.`

// Interpolate variable bindings
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`

// Unescaped template strings
String.raw`In ES5 "\n" is a line-feed.`

// Construct an HTTP request prefix is used to interpret the replacements and construction
GET`http://foo.org/bar?a=${a}&b=${b}
Content-Type: application/json
X-Credentials: ${credentials}
{ "foo": ${foo},
"bar": ${bar}}`(myOnReadyStateChangeHandler);

Destructuring 结构调整

Destructuring allows binding using pattern matching, with support for matching arrays and objects. Destructuring is fail-soft, similar to standard object lookup foo["bar"], producing undefined values when not found.
Destructuring 允许使用模式匹配进行绑定,并支持数组和对象匹配。Destructuring 是失败软处理,类似于标准对象查找 foo["bar"] ,在找不到时会产生 undefined 值。

JavaScript
// list matching
var [a, ,b] = [1,2,3];
a === 1;
b === 3;

// object matching
var { op: a, lhs: { op: b }, rhs: c }
= getASTNode()

// object matching shorthand
// binds `op`, `lhs` and `rhs` in scope
var {op, lhs, rhs} = getASTNode()

// Can be used in parameter position
function g({name: x}) {
console.log(x);
}
g({name: 5})

// Fail-soft destructuring
var [a] = [];
a === undefined;

// Fail-soft destructuring with defaults
var [a = 1] = [];
a === 1;

// Destructuring + defaults arguments
function r({x, y, w = 10, h = 10}) {
return x + y + w + h;
}
r({x:1, y:2}) === 23

Default + Rest + Spread
默认 + 休息 + 展期

Callee-evaluated default parameter values. Turn an array into consecutive arguments in a function call. Bind trailing parameters to an array. Rest replaces the need for arguments and addresses common cases more directly.
调用评估默认参数值。在函数调用中将数组转化为连续参数。将尾部参数绑定到数组。其余部分取代了对 arguments 的需求,能更直接地解决常见问题。

JavaScript
function f(x, y=12) {
// y is 12 if not passed (or passed as undefined)
return x + y;
}
f(3) == 15
JavaScript
function f(x, ...y) {
// y is an Array
return x * y.length;
}
f(3, "hello", true) == 6
JavaScript
function f(x, y, z) {
return x + y + z;
}
// Pass each elem of array as argument
f(...[1,2,3]) == 6

Let + Const 让 + 恒定

Block-scoped binding constructs. let is the new var. const is single-assignment. Static restrictions prevent use before assignment.
块作用域绑定结构。 let 是新的 varconst 是单赋值。静态限制防止在赋值前使用。

JavaScript
function f() {
{
let x;
{
// this is ok since it's a block scoped name
const x = "sneaky";
// error, was just defined with `const` above
x = "foo";
}
// this is ok since it was declared with `let`
x = "bar";
// error, already declared above in this block
let x = "inner";
}
}

Iterators + For..Of 迭代器 + For...Of

Iterator objects enable custom iteration like CLR IEnumerable or Java Iterable. Generalize for..in to custom iterator-based iteration with for..of. Don’t require realizing an array, enabling lazy design patterns like LINQ.
迭代器对象可实现类似 CLR IEnumerable 或 Java Iterable 的自定义迭代。通过 for..offor..in 推广到基于迭代器的自定义迭代。不需要实现数组,从而支持 LINQ 等懒惰设计模式。

JavaScript
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) {
// truncate the sequence at 1000
if (n > 1000)
break;
console.log(n);
}

Iteration is based on these duck-typed interfaces (using TypeScript type syntax for exposition only):
迭代基于这些鸭子类型的接口(使用 TypeScript 类型语法,仅用于说明):

interface IteratorResult {
done: boolean;
value: any;
}
interface Iterator {
next(): IteratorResult;
}
interface Iterable {
[Symbol.iterator](): Iterator
}
Support via polyfill 通过多填充提供支持

In order to use Iterators you must include the Babel polyfill.
要使用迭代器,必须包含 Babel 多填充。

Generators 发电机

Generators simplify iterator-authoring using function* and yield. A function declared as function* returns a Generator instance. Generators are subtypes of iterators which include additional next and throw. These enable values to flow back into the generator, so yield is an expression form which returns a value (or throws).
生成器使用 function*yield 简化了迭代器的编写。声明为 function* 的函数返回一个生成器实例。生成器是迭代器的子类型,包括附加的 nextthrow 。这些功能可使值流回生成器,因此 yield 是返回值(或抛出)的表达式。

Note: Can also be used to enable ‘await’-like async programming, see also ES7 await proposal.
注:也可用于启用类似于 "await "的异步编程,另请参阅 ES7 await 建议。

JavaScript
var fibonacci = {
[Symbol.iterator]: function*() {
var pre = 0, cur = 1;
for (;;) {
var temp = pre;
pre = cur;
cur += temp;
yield cur;
}
}
}

for (var n of fibonacci) {
// truncate the sequence at 1000
if (n > 1000)
break;
console.log(n);
}

The generator interface is (using TypeScript type syntax for exposition only):
生成器接口如下(使用 TypeScript 类型语法,仅供说明):

interface Generator extends Iterator {
next(value?: any): IteratorResult;
throw(exception: any);
}
Support via polyfill 通过多填充提供支持

In order to use Generators you must include the Babel polyfill.
要使用生成器,必须包含 Babel 填充。

Comprehensions 理解

Removed in Babel 6.0
在巴别 6.0 中删除

Unicode 统一码

Non-breaking additions to support full Unicode, including new unicode literal form in strings and new RegExp u mode to handle code points, as well as new APIs to process strings at the 21bit code points level. These additions support building global apps in JavaScript.
为支持完整的 Unicode 增加了非中断功能,包括字符串中新的 unicode 字面形式和处理代码点的新 RegExp u 模式,以及在 21 位代码点级别处理字符串的新 API。这些新增功能支持在 JavaScript 中构建全局应用程序。

JavaScript
// same as ES5.1
"𠮷".length == 2

// new RegExp behaviour, opt-in ‘u’
"𠮷".match(/./u)[0].length == 2

// new form
"\u{20BB7}" == "𠮷"
"𠮷" == "\uD842\uDFB7"

// new String ops
"𠮷".codePointAt(0) == 0x20BB7

// for-of iterates code points
for(var c of "𠮷") {
console.log(c);
}

Modules 模块

Language-level support for modules for component definition. Codifies patterns from popular JavaScript module loaders (AMD, CommonJS). Runtime behaviour defined by a host-defined default loader. Implicitly async model – no code executes until requested modules are available and processed.
为组件定义的模块提供语言级支持。采用流行的 JavaScript 模块加载器(AMD、CommonJS)模式。运行时行为由主机定义的默认加载器定义。隐式异步模式--在请求的模块可用并得到处理之前不执行代码。

JavaScript
// lib/math.js
export function sum(x, y) {
return x + y;
}
export var pi = 3.141593;
JavaScript
// app.js
import * as math from "lib/math";
console.log("2π = " + math.sum(math.pi, math.pi));
JavaScript
// otherApp.js
import {sum, pi} from "lib/math";
console.log("2π = " + sum(pi, pi));

Some additional features include export default and export *:
一些附加功能包括 export defaultexport *

JavaScript
// lib/mathplusplus.js
export * from "lib/math";
export var e = 2.71828182846;
export default function(x) {
return Math.exp(x);
}
JavaScript
// app.js
import exp, {pi, e} from "lib/mathplusplus";
console.log("e^π = " + exp(pi));
Module Formatters 模块格式

Babel can transpile ES2015 Modules to several different formats including Common.js, AMD, System, and UMD. You can even create your own. For more details see the modules docs.
Babel 可将 ES2015 模块转译为多种不同格式,包括 Common.js、AMD、System 和 UMD。你甚至可以创建自己的模块。更多详情,请参阅模块文档。

Module Loaders 模块加载器

Not part of ES2015 不属于 es2015

This is left as implementation-defined within the ECMAScript 2015 specification. The eventual standard will be in WHATWG's Loader specification, but that is currently a work in progress. What is below is from a previous ES2015 draft.
在 ECMAScript 2015 规范中,这部分内容由实现定义。最终的标准将在 WHATWG 的加载器规范中制定,但该规范目前仍在制定过程中。以下内容来自之前的 ES2015 草案。

Module loaders support: 支持模块加载器

  • Dynamic loading 动态加载
  • State isolation 国家隔离
  • Global namespace isolation
    全局命名空间隔离
  • Compilation hooks 编译钩子
  • Nested virtualization 嵌套虚拟化

The default module loader can be configured, and new loaders can be constructed to evaluate and load code in isolated or constrained contexts.
可以配置默认的模块加载器,也可以构建新的加载器,以便在孤立或受限的环境中评估和加载代码。

JavaScript
// Dynamic loading – ‘System’ is default loader
System.import("lib/math").then(function(m) {
alert("2π = " + m.sum(m.pi, m.pi));
});

// Create execution sandboxes – new Loaders
var loader = new Loader({
global: fixup(window) // replace ‘console.log’
});
loader.eval("console.log(\"hello world!\");");

// Directly manipulate module cache
System.get("jquery");
System.set("jquery", Module({$: $})); // WARNING: not yet finalized
Additional polyfill needed
需要额外的填充物

Since Babel defaults to using common.js modules, it does not include the polyfill for the module loader API. Get it here.
由于 Babel 默认使用 common.js 模块,因此不包含模块加载器 API 的 polyfill。在此获取。

Using Module Loader 使用模块加载器

In order to use this, you'll need to tell Babel to use the system module formatter. Also be sure to check out System.js.
要使用此功能,您需要告诉 Babel 使用 system 模块格式化器。此外,请务必查看 System.js。

Map + Set + WeakMap + WeakSet
地图 + 集合 + 弱地图 + 弱集合

Efficient data structures for common algorithms. WeakMaps provides leak-free object-key’d side tables.
常用算法的高效数据结构WeakMaps 提供无泄漏的对象密钥边表。

JavaScript
// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;

// Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;

// Weak Maps
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined

// Weak Sets
var ws = new WeakSet();
ws.add({ data: 42 });
// Because the added object has no other references, it will not be held in the set
Support via polyfill 通过多填充提供支持

In order to support Maps, Sets, WeakMaps, and WeakSets in all environments you must include the Babel polyfill.
为了在所有环境中支持映射、集合、弱映射和弱集合,您必须包含 Babel 填充。

Proxies 代理

Proxies enable creation of objects with the full range of behaviors available to host objects. Can be used for interception, object virtualization, logging/profiling, etc.
代理可以创建具有主机对象全部行为的对象。可用于拦截、对象虚拟化、日志记录/配置等。

JavaScript
// Proxying a normal object
var target = {};
var handler = {
get: function (receiver, name) {
return `Hello, ${name}!`;
}
};

var p = new Proxy(target, handler);
p.world === "Hello, world!";
JavaScript
// Proxying a function object
var target = function () { return "I am the target"; };
var handler = {
apply: function (receiver, ...args) {
return "I am the proxy";
}
};

var p = new Proxy(target, handler);
p() === "I am the proxy";

There are traps available for all of the runtime-level meta-operations:
所有运行时级元操作都有陷阱:

JavaScript
var handler =
{
// target.prop
get: ...,
// target.prop = value
set: ...,
// 'prop' in target
has: ...,
// delete target.prop
deleteProperty: ...,
// target(...args)
apply: ...,
// new target(...args)
construct: ...,
// Object.getOwnPropertyDescriptor(target, 'prop')
getOwnPropertyDescriptor: ...,
// Object.defineProperty(target, 'prop', descriptor)
defineProperty: ...,
// Object.getPrototypeOf(target), Reflect.getPrototypeOf(target),
// target.__proto__, object.isPrototypeOf(target), object instanceof target
getPrototypeOf: ...,
// Object.setPrototypeOf(target), Reflect.setPrototypeOf(target)
setPrototypeOf: ...,
// Object.keys(target)
ownKeys: ...,
// Object.preventExtensions(target)
preventExtensions: ...,
// Object.isExtensible(target)
isExtensible :...
}
Unsupported feature 不支持的功能

Due to the limitations of ES5, Proxies cannot be transpiled or polyfilled. See support in various JavaScript engines.
由于 ES5 的限制,代理无法转置或多填充。请参见各种 JavaScript 引擎的支持。

Symbols 符号

Symbols enable access control for object state. Symbols allow properties to be keyed by either string (as in ES5) or symbol. Symbols are a new primitive type. Optional name parameter used in debugging - but is not part of identity. Symbols are unique (like gensym), but not private since they are exposed via reflection features like Object.getOwnPropertySymbols.
符号允许对对象状态进行访问控制。符号允许通过 string (如 ES5)或 symbol 对属性进行键入。符号是一种新的原始类型。可选的 name 参数用于调试,但不是标识的一部分。符号是唯一的(与 gensym 类似),但不是私有的,因为它们可以通过反射功能(如 Object.getOwnPropertySymbols )暴露出来。

JavaScript
(function() {

// module scoped symbol
var key = Symbol("key");

function MyClass(privateData) {
this[key] = privateData;
}

MyClass.prototype = {
doStuff: function() {
... this[key] ...
}
};

// Limited support from Babel, full support requires native implementation.
typeof key === "symbol"
})();

var c = new MyClass("hello")
c["key"] === undefined
Limited support via polyfill
通过 polyfill 提供有限支持

Limited support requires the Babel polyfill. Due to language limitations, some features can't be transpiled or polyfilled. See core.js's caveats section for more details.
有限的支持需要 Babel 填充。由于语言限制,某些功能无法转置或多填充。详情请参见 core.js 的注意事项部分。

Subclassable Built-ins 可子类化的内置程序

In ES2015, built-ins like Array, Date and DOM Elements can be subclassed.
在 ES2015 中,可以对 ArrayDate 和 DOM Element s 等内置功能进行子类化。

JavaScript
// User code of Array subclass
class MyArray extends Array {
constructor(...args) { super(...args); }
}

var arr = new MyArray();
arr[1] = 12;
arr.length == 2
Partial support 部分支持

Built-in subclassability should be evaluated on a case-by-case basis as classes such as HTMLElement can be subclassed while many such as Date, Array and Error cannot be due to ES5 engine limitations.
HTMLElement 由于 ES5 引擎的限制,很多类(如 DateArrayError )不能被子类化,因此应根据具体情况评估内置的可子类化性。

Math + Number + String + Object APIs
数学 + 数字 + 字符串 + 对象应用程序接口

Many new library additions, including core Math libraries, Array conversion helpers, and Object.assign for copying.
新增了许多库,包括核心数学库、数组转换助手和用于复制的 Object.assign。

JavaScript
Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN") // false

Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) // 5
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2

"abcde".includes("cd") // true
"abc".repeat(3) // "abcabcabc"

Array.from(document.querySelectorAll("*")) // Returns a real Array
Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior
[0, 0, 0].fill(7, 1) // [0,7,7]
[1,2,3].findIndex(x => x == 2) // 1
["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
["a", "b", "c"].keys() // iterator 0, 1, 2
["a", "b", "c"].values() // iterator "a", "b", "c"

Object.assign(Point, { origin: new Point(0,0) })
Limited support from polyfill
来自 polyfill 的有限支持

Most of these APIs are supported by the Babel polyfill. However, certain features are omitted for various reasons (e.g. String.prototype.normalize needs a lot of additional code to support). You can find more polyfills here.
Babel polyfill 支持其中大部分 API。不过,由于各种原因,某些功能被省略了(例如, String.prototype.normalize 需要大量额外代码才能支持)。您可以在这里找到更多 polyfills。

Binary and Octal Literals
二进制和八进制字面量

Two new numeric literal forms are added for binary (b) and octal (o).
新增了二进制 ( b ) 和八进制 ( o ) 两种数字字面形式。

JavaScript
0b111110111 === 503 // true
0o767 === 503 // true
Only supports literal form
仅支持字面形式

Babel is only able to transform 0o767 and not Number("0o767").
巴别只能改造 0o767 ,而不能改造 Number("0o767")

Promises 承诺

Promises are a library for asynchronous programming. Promises are a first class representation of a value that may be made available in the future. Promises are used in many existing JavaScript libraries.
Promises 是一个异步编程库。Promises 是未来可能提供的值的一级表示。许多现有的 JavaScript 库都使用了 Promises。

JavaScript
function timeout(duration = 0) {
return new Promise((resolve, reject) => {
setTimeout(resolve, duration);
})
}

var p = timeout(1000).then(() => {
return timeout(2000);
}).then(() => {
throw new Error("hmm");
}).catch(err => {
return Promise.all([timeout(100), timeout(200)]);
})
Support via polyfill 通过多填充提供支持

In order to support Promises you must include the Babel polyfill.
为了支持 Promises,您必须包含 Babel polyfill。

Reflect API 反射 API

Full reflection API exposing the runtime-level meta-operations on objects. This is effectively the inverse of the Proxy API, and allows making calls corresponding to the same meta-operations as the proxy traps. Especially useful for implementing proxies.
完全反射 API,公开了对象的运行级元操作。这实际上是代理 API 的反向,允许调用与代理陷阱相同的元操作。对于实现代理尤其有用。

JavaScript
var O = {a: 1};
Object.defineProperty(O, 'b', {value: 2});
O[Symbol('c')] = 3;

Reflect.ownKeys(O); // ['a', 'b', Symbol(c)]

function C(a, b){
this.c = a + b;
}
var instance = Reflect.construct(C, [20, 22]);
instance.c; // 42
Support via polyfill 通过多填充提供支持

In order to use the Reflect API you must include the Babel polyfill.
要使用 Reflect API,您必须包含 Babel 填充程序。

Tail Calls 尾部呼叫

Calls in tail-position are guaranteed to not grow the stack unboundedly. Makes recursive algorithms safe in the face of unbounded inputs.
尾部位置的调用保证堆栈不会无限制地增长。这使得递归算法在面对无限制输入时是安全的。

JavaScript
function factorial(n, acc = 1) {
"use strict";
if (n <= 1) return acc;
return factorial(n - 1, n * acc);
}

// Stack overflow in most implementations today,
// but safe on arbitrary inputs in ES2015
factorial(100000)
Temporarily Removed in Babel 6
在巴别 6 中暂时删除

Only explicit self referencing tail recursion was supported due to the complexity and performance impact of supporting tail calls globally. Removed due to other bugs and will be re-implemented.
由于支持全局尾部调用的复杂性和对性能的影响,只支持显式自引用尾部递归。由于其他错误已删除,将重新实现。