ECMAScript 6 (ECMAScript 2015 とも呼ばれます) は、ECMAScript 標準の最新バージョンです。 ES6 は言語の重要なアップデートであり、2009 年に ES5 が標準化されて以来、初めての言語のアップデートです。現在、主要な 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 クラスは、プロトタイプベースの OO パターンを単純化したものです。単一の便利な宣言型があると、クラス パターンが使いやすくなり、相互運用性が促進されます。クラスは、プロトタイプベースの継承、スーパーコール、インスタンスおよび静的メソッドとコンストラクターをサポートします。
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 の割り当ての分割
呼び出し先が評価したデフォルトのパラメーター値。配列を関数呼び出しの連続する引数に変換します。後続パラメータを配列にバインドします。 REST は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 ステートメント
Iterator オブジェクトにより、CLR IEnumerable や Java Iterable などのカスタム反復が可能になります。 for..of
を使用してfor..in
カスタム イテレータベースの反復に一般化します。配列を実現する必要がないため、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
ジェネレーターは、 function*
とyield
を使用してイテレーターの作成を簡素化します。 function* として宣言された関数は、Generator インスタンスを返します。ジェネレーターは、追加のnext
およびthrow
含むイテレーターのサブタイプです。これらにより、値をジェネレーターに戻すことができるため、 yield
値を返す (またはスローする) 式形式になります。
注: 「await」のような非同期プログラミングを有効にするために使用することもできます。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 反復プロトコル
文字列内の新しい Unicode リテラル形式とコード ポイントを処理するための新しい RegExp u
モード、および 21 ビット コード ポイント レベルで文字列を処理するための新しい API など、完全な Unicode をサポートするための非破壊的な追加。これらの追加機能により、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 の詳細情報: import ステートメント、export ステートメント
モジュールローダーは以下をサポートします。
デフォルトのモジュール ローダーを構成したり、分離または制約されたコンテキストでコードを評価およびロードするための新しいローダーを構築したりできます。
// 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 の詳細情報: マップ、セット、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
パラメータですが、ID の一部ではありません。シンボルは一意ですが (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
という名前の関数のオブジェクト構築では、2 つのフェーズが使用されるようになりました (どちらも仮想的にディスパッチされます)。
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
コア数学ライブラリ、配列変換ヘルパー、文字列ヘルパー、コピー用の Object.assign など、多くの新しいライブラリが追加されました。