ECMAScript 2015, also known as ES6, is a fundamental version of the ECMAScript standard.
ECMAScript 2015,也称为ES6,是ECMAScript标准的基本版本。
Published 4 years after the latest standard revision, ECMAScript 5.1, it also marked the switch from edition number to year number.
在最新的标准修订版 ECMAScript 5.1 发布4年后 ,它也标志着从版本号到年份的转换。
So it should not be named as ES6 (although everyone calls it as such) but ES2015 instead.
因此,不应将其命名为ES6 (尽管每个人都这样称呼),而应将其命名为 ES2015。
ES5 was 10 years in the making, from 1999 to 2009, and as such it was also a fundamental and very important revision of the language, but now much time has passed that it’s not worth discussing how pre-ES5 code worked.
从1999年到2009年,ES5诞生了10年,因此它也是该语言的基本且非常重要的修订版,但是现在已经过去了很多时间,因此不值得讨论ES5之前的代码是如何工作的。
Since this long time passed between ES5.1 and ES6, the release is full of important new features and major changes in suggested best practices in developing JavaScript programs. To understand how fundamental ES2015 is, just keep in mind that with this version, the specification document went from 250 pages to ~600.
自从ES5.1和ES6之间经历了如此长的时间以来,此版本充满了重要的新功能以及开发JavaScript程序时建议的最佳实践的重大变化。 要了解ES2015的基础,请记住,使用此版本,规范文档从250页增加到600页。
This article describes the most important changes.
本文介绍了最重要的更改。
箭头功能 (Arrow Functions)
Arrow functions since their introduction changed how most JavaScript code looks (and works).
自箭头函数引入以来,它们改变了大多数JavaScript代码的外观(和工作方式)。
Visually, it’s a simple and welcome change, from:
从外观上看,这是一个简单而受欢迎的更改,来自:
const something = function something() {
//...
}
to
至
const something = () => {
//...
}
And if the function body is a one-liner, just:
如果函数主体是单行的,则:
const something = () => doSomething()
Also, if you have a single parameter, you could write:
另外,如果只有一个参数,则可以编写:
const something = param => doSomething(param)
This is not a breaking change, regular function
s will continue to work just as before.
这不是一个重大变化,常规function
将像以前一样继续工作。
新的this
范围 (A new this
scope)
The this
scope with arrow functions is inherited from the context.
在this
箭头的功能范围从上下文继承。
With regular function
s this
always refers to the nearest function, while with arrow functions this problem is removed, and you won’t need to write var that = this
ever again.
对于常规function
s, this
始终指的是最接近的函数,而对于箭头函数,此问题已消除,并且您无需再次编写var that = this
。
承诺 (Promises)
Promises (check the full guide to promises) allow us to eliminate the famous “callback hell”, although they introduce a bit more complexity (which has been solved in ES2017 with async
, a higher level construct).
承诺(请参阅完整的 Promise 指南 )允许我们消除著名的“回调地狱”,尽管它们引入了更多的复杂性(已在ES2017中使用async
(更高级别的构造方法)解决了)。
Promises have been used by JavaScript developers well before ES2015, with many different libraries implementations (e.g. jQuery, q, deferred.js, vow…), and the standard put a common ground across differences.
JavaScript开发人员早在ES2015之前就已经使用了Promises,它具有许多不同的库实现(例如jQuery,q,deferred.js,vow…),并且该标准在不同点上有共同点。
By using promises you can rewrite this code
通过使用诺言,您可以重写此代码
setTimeout(function() {
console.log('I promised to run after 1s')
setTimeout(function() {
console.log('I promised to run after 2s')
}, 1000)
}, 1000)
as
如
const wait = () => new Promise((resolve, reject) => {
setTimeout(resolve, 1000)
})
wait().then(() => {
console.log('I promised to run after 1s')
return wait()
})
.then(() => console.log('I promised to run after 2s'))
发电机 (Generators)
Generators are a special kind of function with the ability to pause itself, and resume later, allowing other code to run in the meantime.
生成器是一种特殊的功能,具有暂停自身和稍后恢复的功能,允许同时运行其他代码。
See the full JavaScript Generators Guide for a detailed explanation of the topic.
有关该主题的详细说明,请参见完整的JavaScript生成器指南。
let
和const
(let
and const
)
var
is traditionally function scoped.
var
传统上是函数范围的 。
let
is a new variable declaration which is block scoped.
let
是一个新的变量声明,它是块范围的 。
This means that declaring let
variables in a for loop, inside an if or in a plain block is not going to let that variable “escape” the block, while var
s are hoisted up to the function definition.
这意味着在var
循环到函数定义之前,在for循环中,在if或普通块内声明let
变量不会让该变量“退出”该块。
const
is just like let
, but immutable.
const
就像let
一样,但却是一成不变的 。
In JavaScript moving forward, you’ll see little to no var
declarations any more, just let
and const
.
在前进JavaScript中,您几乎看不到var
声明了,只是let
和const
。
const
in particular, maybe surprisingly, is very widely used nowadays with immutability being very popular.
尤其令人惊讶的是, const
在当今已经非常广泛地使用 ,不变性非常流行。
班级 (Classes)
Traditionally JavaScript is the only mainstream language with prototype-based inheritance. Programmers switching to JS from class-based language found it puzzling, but ES2015 introduced classes, which are just syntactic sugar over the inner working, but changed a lot how we build JavaScript programs.
传统上,JavaScript是唯一具有基于原型的继承的主流语言。 从基于类的语言切换到JS的程序员感到困惑,但是ES2015引入了类,这些类只是内部工作的语法糖,但是极大地改变了我们构建JavaScript程序的方式。
Now inheritance is very easy and resembles other object-oriented programming languages:
现在,继承非常容易,并且类似于其他面向对象的编程语言:
class Person {
constructor(name) {
this.name = name
}
hello() {
return 'Hello, I am ' + this.name + '.'
}
}
class Actor extends Person {
hello() {
return super.hello() + ' I am an actor.'
}
}
var tomCruise = new Actor('Tom Cruise')
tomCruise.hello()
(the above program prints “Hello, I am Tom Cruise. I am an actor.”)
(以上程序打印“ 你好,我是汤姆·克鲁斯。我是演员。 ”)
Classes do not have explicit class variable declarations, but you must initialize any variable in the constructor.
类没有显式的类变量声明,但是必须在构造函数中初始化任何变量。
建设者 (Constructor)
Classes have a special method called constructor
which is called when a class is initialized via new
.
类具有称为constructor
的特殊方法,当通过new
初始化类时会调用该方法。
超 (Super)
The parent class can be referenced using super()
.
可以使用super()
引用父类。
吸气剂和二传手 (Getters and setters)
A getter for a property can be declared as
属性的获取器可以声明为
class Person {
get fullName() {
return `${this.firstName} ${this.lastName}`
}
}
Setters are written in the same way:
二传手的书写方式相同:
class Person {
set age(years) {
this.theAge = years
}
}
模组 (Modules)
Before ES2015, there were at least 3 major modules competing standards, which fragmented the community:
在ES2015之前,至少有3个主要模块与标准竞争,这使社区支离破碎:
- AMD AMD公司
- RequireJS 需求JS
- CommonJS 普通JS
ES2015 standardized these into a common format.
ES2015将这些标准标准化为通用格式。
导入模块 (Importing modules)
Importing is done via the import ... from ...
construct:
导入是通过import ... from ...
构造完成的:
import * from 'mymodule'
import React from 'react'
import { React, Component } from 'react'
import React as MyLibrary from 'react'
导出模块 (Exporting modules)
You can write modules and export anything to other modules using the export
keyword:
您可以使用export
关键字编写模块并将任何内容导出到其他模块:
export var number = 2
export function bar() { /* ... */ }
模板文字 (Template Literals)
Template literals are a new syntax to create strings:
模板文字是创建字符串的新语法:
const aString = `A string`
They provide a way to embed expressions into strings, effectively inserting the values, by using the ${a_variable}
syntax:
它们提供了一种使用${a_variable}
语法将表达式嵌入到字符串中,有效地插入值的方法:
const joe = 'test'
const string = `something ${joe}` //something test
You can perform more complex expressions as well:
您还可以执行更复杂的表达式:
const string = `something ${1 + 2 + 3}`
const string2 = `something ${doSomething() ? 'x' : 'y' }`
and strings can span over multiple lines:
并且字符串可以跨越多行:
const string3 = `Hey
this
string
is awesome!`
Compare how we used to do multiline strings pre-ES2015:
比较一下我们在ES2015之前使用多行字符串的方式:
var str = 'One\n' +
'Two\n' +
'Three'
默认参数 (Default parameters)
Functions now support default parameters:
函数现在支持默认参数:
const someFunction = function(index = 0, testing = true) { /* ... */ }
someFunction()
点差运算符 (The spread operator)
You can expand an array, an object or a string using the spread operator ...
.
您可以使用传播运算符...
扩展数组,对象或字符串。
Let’s start with an array example. Given
让我们从一个数组示例开始。 给定
const a = [1, 2, 3]
you can create a new array using
您可以使用创建新数组
const b = [...a, 4, 5, 6]
You can also create a copy of an array using
您还可以使用创建一个数组的副本
const c = [...a]
This works for objects as well. Clone an object with:
这也适用于对象。 克隆对象:
const newObj = { ...oldObj }
Using strings, the spread operator creates an array with each char in the string:
使用字符串,spread运算符使用字符串中的每个字符创建一个数组:
const hey = 'hey'
const arrayized = [...hey] // ['h', 'e', 'y']
This operator has some pretty useful applications. The most important one is the ability to use an array as function argument in a very simple way:
该运算符具有一些非常有用的应用程序。 最重要的一个功能是以一种非常简单的方式将数组用作函数参数的能力:
const f = (arg1, arg2) => {}
const a = [1, 2]
f(...a)
(in the past you could do this using f.apply(null, a)
but that’s not as nice and readable)
(过去,您可以使用f.apply(null, a)
来执行此操作f.apply(null, a)
但这并不那么好看而且可读性强)
销毁工作 (Destructuring assignments)
Given an object, you can extract just some values and put them into named variables:
给定一个对象,您可以仅提取一些值并将其放入命名变量中:
const person = {
firstName: 'Tom',
lastName: 'Cruise',
actor: true,
age: 54, //made up
}
const {firstName: name, age} = person
name
and age
contain the desired values.
name
和age
包含所需的值。
The syntax also works on arrays:
该语法也适用于数组:
const a = [1,2,3,4,5]
const [first, second] = a
This statement creates 3 new variables by getting the items with index 0, 1, 4 from the array a
:
该语句通过从数组a
获取索引为0、1、4的项来创建3个新变量:
const [first, second, , , fifth] = a
增强的对象文字 (Enhanced Object Literals)
In ES2015 Object Literals gained superpowers.
在ES2015中,Object Literals获得了超能力。
包含变量的语法更简单 (Simpler syntax to include variables)
Instead of doing
而不是做
const something = 'y'
const x = {
something: something
}
you can do
你可以做
const something = 'y'
const x = {
something
}
原型 (Prototype)
A prototype can be specified with
原型可以用
const anObject = { y: 'y' }
const x = {
__proto__: anObject
}
超() (super())
const anObject = { y: 'y', test: () => 'zoo' }
const x = {
__proto__: anObject,
test() {
return super.test() + 'x'
}
}
x.test() //zoox
动态特性 (Dynamic properties)
const x = {
['a' + '_' + 'b']: 'z'
}
x.a_b //z
循环循环 (For-of loop)
ES5 back in 2009 introduced forEach()
loops. While nice, they offered no way to break, like for
loops always did.
早在2009年,ES5就引入了forEach()
循环。 虽然不错,但它们没有提供中断的方法,就像for
循环总是一样。
ES2015 introduced the for-of
loop, which combines the conciseness of forEach
with the ability to break:
ES2015引入了for-of
循环 ,该循环结合了forEach
的简洁性和打破能力:
//iterate over the value
for (const v of ['a', 'b', 'c']) {
console.log(v);
}
//get the index as well, using `entries()`
for (const [i, v] of ['a', 'b', 'c'].entries()) {
console.log(i, v);
}
地图和设置 (Map and Set)
Map and Set (and their respective garbage collected WeakMap and WeakSet) are the official implementations of two very popular data structures.
Map和Set (以及它们各自的垃圾收集WeakMap和WeakSet )是两个非常流行的数据结构的正式实现。
新的String方法 (New String methods)
Any string value got some new instance methods:
任何字符串值都有一些新的实例方法:
repeat()
repeats the strings for the specificed number of times:'Ho'.repeat(3) //HoHoHo
repeat()
将字符串重复特定的次数:'Ho'.repeat(3) //HoHoHo
codePointAt()
handles retrieving the Unicode code of characters that cannot be represented by a single 16-bit UTF-16 unit, but need 2 insteadcodePointAt()
处理检索无法由单个16位UTF-16单元表示但需要2个代替的字符的Unicode代码
新对象方法 (New Object methods)
ES6 introduced several static methods under the Object namespace:
ES6在对象名称空间下引入了几种静态方法:
Object.is()
determines if two values are the same valueObject.is()
确定两个值是否相同Object.assign()
used to shallow copy an objectObject.assign()
用于浅复制对象Object.setPrototypeOf
sets an object prototypeObject.setPrototypeOf
设置对象原型