ECMAScript 6,也稱為 ECMAScript 2015,是 ECMAScript 標準的最新版本。 ES6 是該語言的重大更新,也是自 2009 年 ES5 標準化以來該語言的首次更新。
有關 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 解構作業
被呼叫者評估的預設參數值。將數組轉換為函數呼叫中的連續參數。將尾隨參數綁定到數組。休息取代了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 資訊:預設參數、Rest 參數、Spread 運算符
塊範圍的綁定構造。 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..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 for...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 迭代協議
支援完整 Unicode 的不間斷添加,包括字串中的新 Unicode 文字形式和用於處理代碼點的新 RegExp u
模式,以及用於在 21 位元代碼點層級處理字串的新 API。這些新增功能支援用 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
新增了許多新的庫,包括核心數學庫、數組轉換助手、字串助手和用於複製的 Object.assign。