ECMAScript 6, также известный как ECMAScript 2015, — это последняя версия стандарта ECMAScript. ES6 представляет собой значительное обновление языка и первое обновление языка с тех пор, как ES5 был стандартизирован в 2009 году. Реализация этих функций в основных движках JavaScript уже ведется.
Полную спецификацию языка ECMAScript 6 см. в стандарте ES6.
ES6 включает в себя следующие новые функции:
Стрелки — это сокращение функции, использующее синтаксис =>
. Они синтаксически аналогичны соответствующей функции в C#, Java 8 и CoffeeScript. Они поддерживают как тела блоков операторов, так и тела выражений, которые возвращают значение выражения. В отличие от функций, стрелки имеют ту же лексику this
что и окружающий их код.
// Expression bodies
var odds = evens . map ( v => v + 1 ) ;
var nums = evens . map ( ( v , i ) => v + i ) ;
var pairs = evens . map ( v => ( { even : v , odd : v + 1 } ) ) ;
// 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 ) ) ;
}
}
Дополнительная информация: Стрелочные функции MDN.
Классы ES6 — это простой сахар над объектно-ориентированным шаблоном на основе прототипа. Наличие единой удобной декларативной формы упрощает использование шаблонов классов и способствует совместимости. Классы поддерживают наследование на основе прототипов, супервызовы, экземпляры и статические методы и конструкторы.
class SkinnedMesh extends THREE . Mesh {
constructor ( geometry , materials ) {
super ( geometry , materials ) ;
this . idMatrix = SkinnedMesh . defaultMatrix ( ) ;
this . bones = [ ] ;
this . boneMatrices = [ ] ;
//...
}
update ( camera ) {
//...
super . update ( ) ;
}
get boneCount ( ) {
return this . bones . length ;
}
set matrixType ( matrixType ) {
this . idMatrix = SkinnedMesh [ matrixType ] ( ) ;
}
static defaultMatrix ( ) {
return new THREE . Matrix4 ( ) ;
}
}
Дополнительная информация: Классы MDN.
Литералы объектов расширены для поддержки установки прототипа при создании, сокращения для foo: foo
, определения методов, выполнения супервызовов и вычисления имен свойств с помощью выражений. Вместе они также сближают литералы объектов и объявления классов и позволяют объектно-ориентированному проектированию пользоваться некоторыми из тех же удобств.
var obj = {
// __proto__
__proto__ : theProtoObj ,
// Shorthand for ‘handler: handler’
handler ,
// Methods
toString ( ) {
// Super calls
return "d " + super . toString ( ) ;
} ,
// Computed (dynamic) property names
[ 'prop_' + ( ( ) => 42 ) ( ) ] : 42
} ;
Дополнительная информация: Грамматика и типы MDN: литералы объектов.
Строки шаблонов предоставляют синтаксический сахар для построения строк. Это похоже на функции интерполяции строк в Perl, Python и других. При желании можно добавить тег, позволяющий настраивать конструкцию строки, избегая атак путем внедрения или создания структур данных более высокого уровня из содержимого строки.
// Basic literal string creation
`In JavaScript 'n' is a line-feed.`
// Multiline strings
`In JavaScript this is
not legal.`
// String interpolation
var name = "Bob" , time = "today" ;
`Hello ${ name } , how are you ${ time } ?`
// Construct an HTTP request prefix is used to interpret the replacements and construction
POST `http://foo.org/bar?a= ${ a } &b= ${ b }
Content-Type: application/json
X-Credentials: ${ credentials }
{ "foo": ${ foo } ,
"bar": ${ bar } }` ( myOnReadyStateChangeHandler ) ;
Дополнительная информация: Строки шаблона MDN.
Деструктуризация позволяет выполнять связывание с использованием сопоставления с образцом с поддержкой сопоставления массивов и объектов. Деструктуризация является отказоустойчивой, аналогично стандартному поиску объектов foo["bar"]
, выдающему undefined
значения, если они не найдены.
// list matching
var [ a , , b ] = [ 1 , 2 , 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 ;
Дополнительная информация: Задание по деструктуризации MDN.
Значения параметров по умолчанию, оцененные вызываемым объектом. Превратите массив в последовательные аргументы при вызове функции. Привяжите конечные параметры к массиву. Отдых заменяет необходимость в arguments
и более непосредственно рассматривает распространенные случаи.
function f ( x , y = 12 ) {
// y is 12 if not passed (or passed as undefined)
return x + y ;
}
f ( 3 ) == 15
function f ( x , ... y ) {
// y is an Array
return x * y . length ;
}
f ( 3 , "hello" , true ) == 6
function f ( x , y , z ) {
return x + y + z ;
}
// Pass each elem of array as argument
f ( ... [ 1 , 2 , 3 ] ) == 6
Дополнительная информация о MDN: параметры по умолчанию, остальные параметры, оператор распространения.
Конструкции привязки с областью действия блока. let
это новый var
. const
— это одно присвоение. Статические ограничения предотвращают использование до назначения.
function f ( ) {
{
let x ;
{
// okay, block scoped name
const x = "sneaky" ;
// error, const
x = "foo" ;
}
// error, already declared in block
let x = "inner" ;
}
}
Дополнительная информация о MDN: оператор let, оператор const
Объекты-итераторы позволяют выполнять пользовательскую итерацию, например CLR IEnumerable или Java Iterable. Обобщите for..in
до пользовательской итерации на основе итератора с помощью for..of
. Не требуйте реализации массива, используйте шаблоны ленивого проектирования, такие как LINQ.
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 ) ;
}
Итерация основана на этих интерфейсах с утиным типом (с использованием синтаксиса типов TypeScript только для демонстрации):
interface IteratorResult {
done : boolean ;
value : any ;
}
interface Iterator {
next ( ) : IteratorResult ;
}
interface Iterable {
[ Symbol . iterator ] ( ) : Iterator
}
Дополнительная информация: MDN для...of
Генераторы упрощают создание итераторов, используя function*
и yield
. Функция, объявленная как function*, возвращает экземпляр Generator. Генераторы — это подтипы итераторов, которые включают дополнительные next
и throw
. Они позволяют значениям возвращаться обратно в генератор, поэтому yield
— это форма выражения, которая возвращает значение (или выдает результат).
Примечание. Также может использоваться для включения асинхронного программирования, подобного «ожиданию», см. также предложение ES7 await
.
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 ) ;
}
Интерфейс генератора (используется синтаксис типов TypeScript только для демонстрации):
interface Generator extends Iterator {
next ( value ?: any ) : IteratorResult ;
throw ( exception : any ) ;
}
Дополнительная информация: Протоколы итерации MDN.
Неразрушающие дополнения для полной поддержки Юникода, включая новую литеральную форму Юникода в строках и новый режим RegExp u
для обработки кодовых точек, а также новые API для обработки строк на уровне 21-битных кодовых точек. Эти дополнения поддерживают создание глобальных приложений на JavaScript.
// same as ES5.1
"?" . length == 2
// new RegExp behaviour, opt-in ‘u’
"?" . match ( / . / u ) [ 0 ] . length == 2
// new form
"u{20BB7}" == "?" == "uD842uDFB7"
// new String ops
"?" . codePointAt ( 0 ) == 0x20BB7
// for-of iterates code points
for ( var c of "?" ) {
console . log ( c ) ;
}
Дополнительная информация: MDN RegExp.prototype.unicode.
Поддержка модулей для определения компонентов на уровне языка. Кодифицирует шаблоны популярных загрузчиков модулей JavaScript (AMD, CommonJS). Поведение во время выполнения определяется загрузчиком по умолчанию, определенным хостом. Неявно асинхронная модель – код не выполняется до тех пор, пока запрошенные модули не будут доступны и не обработаны.
// lib/math.js
export function sum ( x , y ) {
return x + y ;
}
export var pi = 3.141593 ;
// app.js
import * as math from "lib/math" ;
alert ( "2π = " + math . sum ( math . pi , math . pi ) ) ;
// otherApp.js
import { sum , pi } from "lib/math" ;
alert ( "2π = " + sum ( pi , pi ) ) ;
Некоторые дополнительные функции включают export default
и export *
:
// lib/mathplusplus.js
export * from "lib/math" ;
export var e = 2.71828182846 ;
export default function ( x ) {
return Math . log ( x ) ;
}
// app.js
import ln , { pi , e } from "lib/mathplusplus" ;
alert ( "2π = " + ln ( e ) * pi * 2 ) ;
Дополнительная информация MDN: оператор импорта, оператор экспорта
Загрузчики модулей поддерживают:
Можно настроить загрузчик модулей по умолчанию, а также можно создать новые загрузчики для оценки и загрузки кода в изолированных или ограниченных контекстах.
// 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
Эффективные структуры данных для распространенных алгоритмов. WeakMaps предоставляет боковые таблицы с объектными ключами без утечек.
// 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
Дополнительная информация о MDN: Map, Set, WeakMap, WeakSet.
Прокси позволяют создавать объекты с полным спектром поведения, доступным для хост-объектов. Может использоваться для перехвата, виртуализации объектов, журналирования/профилирования и т. д.
// 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!' ;
// 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' ;
Для всех метаопераций уровня времени выполнения доступны ловушки:
var handler =
{
get :... ,
set :... ,
has :... ,
deleteProperty :... ,
apply :... ,
construct :... ,
getOwnPropertyDescriptor :... ,
defineProperty :... ,
getPrototypeOf :... ,
setPrototypeOf :... ,
enumerate :... ,
ownKeys :... ,
preventExtensions :... ,
isExtensible :...
}
Дополнительная информация: MDN-прокси.
Символы позволяют контролировать доступ к состоянию объекта. Символы позволяют присваивать свойствам ключи либо с помощью string
(как в ES5), либо с symbol
. Символы — это новый примитивный тип. Необязательный параметр description
, используемый при отладке, но не являющийся частью удостоверения. Символы уникальны (например, gensym), но не являются частными, поскольку они предоставляются через функции отражения, такие как Object.getOwnPropertySymbols
.
var MyClass = ( function ( ) {
// module scoped symbol
var key = Symbol ( "key" ) ;
function MyClass ( privateData ) {
this [ key ] = privateData ;
}
MyClass . prototype = {
doStuff : function ( ) {
... this [ key ] . . .
}
} ;
return MyClass ;
} ) ( ) ;
var c = new MyClass ( "hello" )
c [ "key" ] === undefined
Дополнительная информация: Символ MDN.
В ES6 встроенные модули, такие как Array
, Date
и DOM Element
, могут быть подклассами.
Создание объекта для функции с именем Ctor
теперь использует две фазы (обе выполняются виртуально):
Ctor[@@create]
чтобы выделить объект, установив любое специальное поведение. Известный символ @@create
доступен через Symbol.create
. Встроенные модули теперь явно отображают @@create
.
// Pseudo-code of Array
class Array {
constructor ( ... args ) { /* ... */ }
static [ Symbol . create ] ( ) {
// Install special [[DefineOwnProperty]]
// to magically update 'length'
}
}
// User code of Array subclass
class MyArray extends Array {
constructor ( ... args ) { super ( ... args ) ; }
}
// Two-phase 'new':
// 1) Call @@create to allocate object
// 2) Invoke constructor on new instance
var arr = new MyArray ( ) ;
arr [ 1 ] = 12 ;
arr . length == 2
Множество новых дополнений к библиотекам, включая основные библиотеки Math, помощники преобразования массивов, помощники строк и Object.assign для копирования.