當前位置:
首頁 > 科技 > 【第1006期】ECMAScript 6 新特性

【第1006期】ECMAScript 6 新特性

前言

ES8 都提出來了,今天給我看 ES6 會不會呵呵呢?

今日早讀文章由 @ 池盛星 翻譯分享。

正文從這開始~

ECMAScript 6, 也就是ECMAScript 2015, 是最新版的ECMAScript標準. ES6是JavaScript語言的重要更新, 同時也是自2009年的ES5以來的第一次正式更新. 目前, 主要的JavaScript引擎正在實現這些功能.

要查看完整的ES6標準規範, 請點擊ECMAScript 2015 Language Specification.

ES6包含以下新特性:

arrows

classes

enhanced object literals

template strings

destructuring

default + rest + spred

let + const

iterators + for..of

genetators

unicode

modules

module loaders

map + set + weakmap + weakset

proxies

symbols

subclassable built-ins

promises

math + number + string + array + object APIs

binary and octal literals

reflect api

tail calls

Arrows 箭頭函數

Arrows是函數的一種縮寫, 表現形式為=>. 它們在語法上, 類似於C#, Java 8以及CoffeeScript. 它們不僅支持塊級函數體, 同時也支持帶返回值的表達式函數體. 與普通函數的this作用域不同, 箭頭函數內部與它周圍代碼共享this作用域. 即, this指向同一個東西 .

// Expression bodies 表達式函數體

letodds=evens.map(v=>v+1);

letnums=evens.map((v,i)=>v+i);

letpairs=evens.map(v=>({even:v,odd:v+1}));

// Statement bodies 塊級函數體

nums.forEach(v=>{

if(v%5===){

fives.push(v);

}

});

// Lexical this: this 作用域

letbob={

_name:"Bob",

_friends:[],

printFriends(){

this._friends.forEach(f=>console.log(this._name+" knows "+f));

}

}

更多信息參考MDN: Arrow functions

Classes 類

ES6的類是基於prototype的OO模式的語法糖. 擁有簡單方便的聲明式格式, 使得類模式更易於使用, 並鼓勵互操作性. 類支持基於prototype的繼承, 超級調用(super calls), 實例(instance), 靜態方法(static methods)以及構造函數 .

// Classes

classSkinnedMeshextendsTHREE.Mesh{

constructor(geometry,metrials){

super(geometry,meterials);

this.idMatrix=SkinnedMesh.defaultMatrix();

this.bones=[];

this.boneMatrices=[];

// ...

}

update(camera){

// ...

super.update();

}

getboneCount(){

returnthis.bones.length;

}

setmatrixType(matrixType){

this.idMatrix=SkinnedMesh[matrixType]();

}

staticdefaultMatrix(){

returnnewTHREE.Matrix4();

}

}

更多信息參考MDN: Classes

Enhanced Object Literals 增強的對象字面量

對象字面量被擴展用於支持在構建時設置prototype, foo: foo的簡寫, 定義方法, 超級調用(super calls)以及使用表達式計算屬性名稱. 同時, 這些也將對象字面量和類聲明更緊密的結合在一起, 並使基於對象的設計獲得相同的便利 .

letobj={

// __proto__

__proto__:theProtoObj,

// Shorthand for `handler: handler`

handler,

// Methods

toString(){

// super calls

return"d "+super.toString();

},

// Computed (dynamic) property names

[ prop_ +(()=>42)]:42

}

更多信息請參考MDN: Grammar and types: Object literals

Template Strings 模板字元串

模板字元串(template strings)提供了一個構建字元串的語法糖. 這有點類似於Perl, Python以及其它類似語言的字元串插入功能. 作為一種選擇, 可以添加標籤(tag)以允許字元串在構建時被定製, 避免注入攻擊或者從字元串內容構建更高級別的數據結構 .

// 簡單字面量字元串

`In JavaScript
is a line-feed.`

// 多行字元串

`In JavaScript this is

not legal.`

// 字元串插值

letname="Bob";

lettime="today";

`Hello${name}, how are you${time}?`

// 構造一個HTTP請求前綴, 用於演繹替換和構造

POST`http://foo.org/bar?a=${a}&b=${b}

Content-type: application/json

X-Credentials:${credentials}

{"foo":${foo},

"bar":${bar}}`(myOnReadyStateChangeHandler);

更多信息請參考MDN: Template literals

Destructuring 解構

解構允許使用模式匹配進行綁定, 支持匹配數組和對象. 解構是故障弱化(指未匹配上時, 也不會出錯, 而是產生一個undefined值), 類似於標準對象查找foo["bar"], 當未找到時, 產生一個undefined 值 .

// list匹配

let[a,,b]=[1,2,3];

// a=1; b=3

// object匹配

let{op:a,lhs:{op:b},rhs:c}=getASTNode();

// object匹配簡寫

// 在scope內綁定`op`, `lhs`及`rhs`

let{op,lhs,rhs}=getASTNode();

// 可用於參數位置

functiong({name:x}){

console.log(x);// 5

}

g({name:5});

// 故障弱化解構

let[a]=[];

a===undefined;

// 故障弱化解構, 帶默認值

let[a=1]=[];

a===1;

更多信息請參考MDN: Destructuring assignment

Default + Rest + Spread 默認參數, 剩餘參數(Rest Parameters), Spread語法

為函數的參數設置默認值. 將傳入的參數的剩餘參數綁定到數組. 使用...操作符, 將數組解構成參數列表 .

// 給參數設置默認值

functionf(x,y=12){

// 如果沒有傳入y的值(或者傳入的是undefined), 那麼y就等於默認的值12

returnx+y;

}

f(3)===15

// 將傳入的參數的剩餘參數綁定到數組

functionf(x,...y){

// y是一個數組Array

returnx*y.length;

}

f(3,"hello",true)===6;

// 使用...操作符, 將數組解構成參數列表

functionf(x,y,z){

returnx+y+z;

}

// 傳入一個數組作為參數

f(...[1,2,3])===6;

更多信息請參考MDN: Default parameters, Rest parameters, Spread syntax

Let + Const

用let和const代替var, 定義塊級作用域的變數 .

functionf(){

letx;

{

// 由於let定義的是塊級作用域的變數, 所以這樣是合法的

constx="sneaky";

// 由於const定義的是常量, 所以不能再進行賦值操作

x="foo";

}

// 由於在函數f()內, 前面已經有let x的定義, 所以不能再次定義

// 報錯: Uncaught SyntaxError: Identifier x has already been declared

letx="inner";

}

更多信息請參考MDN: let, const

Iterators + for..of 迭代器 for..of

迭代器對象啟用自定義迭代, 如CLR IEnumberable或Java Iterable. 通用於for..in基於自定義迭代器的迭代, for..of用法類似. 不需要是一個真正的數組, 像LINQ一樣, 啟用懶設計模式 .

letfibonacci={

[Symbol.iterator](){

letpre=;

letcur=1;

return{

next(){

[pre,cur]=[cur,pre+cur];

return{done:false,value:cur}

}

}

}

}

for(varnoffibonacci){

// 在1000處截斷序列

if(n>1000){

break;

}

console.log(n);

}

迭代器對象啟用自定義迭代,如CLR IEnumerable或Java Iterable。 通用於...的自定義基於迭代器的迭代。 不需要實現陣列,實現LINQ等懶人設計模式。

更多信息請參考MDN: for...of

Generators

Generators使用function* 和yield簡化iterator-autoring. 聲明為function*的函數返回一個Generator實例. Generators是迭代器的子類型, 包括next和throw. 這些可能的值返回到generator, 因此yield是一個表達式, 它返回值或throws.

注意: 同時也可以用來啟用"await"類似的非同步編程, 請參閱ES7await 提案 .

letfibonacci={

[Symbol.iterator]:function*(){

letpre=;

letcur=1;

for(;;){

lettemp=pre;

pre=cur;

cur+=temp;

yieldcur;

}

}

}

for(letpoffibonacci){

// 在1000處截斷序列

if(n>1000){

break;

}

console.log(n);

}

使用generator介面:(使用TypeScript 語法)

interfaceGeneratorextendsIterator{

next(value?:any):IteratorResult;

throw(exception:any);

}

更多信息請參考MDN: Iteration protocols

Unicode

// same as ES5.1

"".length==2

// new RegExp behaviour, opt-in 『u』

"".match(/./u)[].length==2

// new form

"u"==""=="uD842uDFB7"

// new String ops

"".codePointAt()==0x20BB7

// for-of iterates code points

for(varcof""){

console.log(c);

}

Modules 模塊

語言級支持模塊化組件定義. 吸收流行的JavaScript模塊載入方式(AMD, CommonJS). 由host-defined默認載入器定義運行時行為. 隱式非同步模型 -- 在請求的模塊可用和處理之前, 不執行任何代碼 .

// lib/math.js

exportfunctionsum(x,y){

returnx+y;

}

exportletpi=3.141593;

// app.js

import*asmathfrom"lib/math";

console.log(`2π =${math.sum(math.pi,math.pi)}`);

// otherApp.js

import{sum,pi}from"lib/math";

console.log(`2π =${sum(pi,pi)}`);

其他更多的export default和export * 的功能:

// lib/mathPlusPlus.js

export*from"lib/math";

exportlete=2.71828182846;

exportdefaultfunction(x){

returnMath.log(x);

}

// app.js

importln,{pi,e}from"lib/mathPlusPlus";

console.log(`2π =${ln(e)*pi*2}`);

更多信息請參考MDN: import, export

Module Loaders 模塊載入器

模塊載入器支持:

Dynamic loading 動態載入

State isolation

Global namespace isolation

Complilation hooks

Nested virtualization

可用配置默認模塊載入器, 並且可以構造新的載入器以在隔離或約束上下文中評估和載入代碼 .

// Dynamic loading - "System" is default loader

System.import("lib/math").then(function(m){

console.log(`2π =${m.sum(m.pi,m.pi)}`);

});

// Create execution sandboxes - new Loaders

letloader=newLoader({

global:fixup(window)// replace "console.log"

});

loader.eval("console.log( hello world! );");

// Directly manipulate module cache

System.get( jquery );

System.set( jquery ,Module({$:$}));// 警告: 還沒有最終定稿

Map, Set, WeakMap, WeakSet

常用演算法的高效數據結構. WeakMaps提供了無密鑰(leak-free) object-key的side tables.

// Sets

lets=newSet();

s.add("hello").add("goodbye").add("hello");

// s.size === 2;

// s.has("hello") === true;

// Maps

letm=newMap();

m.set("hello",42);

m.set(s,34);

// m.get(s) === 34;

// Weak Sets

letws=newWeakSet();

ws.add({data:42});

// Weak Maps

letwm=newWeakMap();

wm.set(s,{extra:42});

// wm.size === undefined;

更多信息請參考MDN: Map, Set, WeakMap, WeakSet

Proxies 代理

代理可以創建具有可用於託管對象的全部行為的對象 .

// Proxying a normal object

lettarget={};

lethandler={

get:function(receiver,name){

return`Hello,${name}!`;

}

}

letp=newProxy(target,handler);

// p.world === `Hello, world!`;

// Proxying a function object

lettarget=function(){return`I am the target`;};

lethandler={

apply:function(receiver,...args){

return`I am the proxy.`;

}

}

letp=newProxy(target,handler);

// p() === `I am the proxy.`;

有可用於所有運行時元操作(meta-operations)的陷阱(traps):

varhandler=

{

get:...,

set:...,

has:...,

deleteProperty:...,

apply:...,

construct:...,

getOwnPropertyDescriptor:...,

defineProperty:...,

getPrototypeOf:...,

setPrototypeOf:...,

enumerate:...,

ownKeys:...,

preventExtensions:...,

isExtensible:...

}

更多信息請參考MDN: MDN Proxy

Symbols 一種新的原始數據類型

Symbols允許對象狀態的訪問控制. Symbols允許屬性是一個字元串(如ES5)或者symbol. Symbols是一種新的原始數據類型. 可選描述參數用於調試, 但不是身份的一部分. Symbols是唯一的(如gensym), 但不是私有的, 因為他們通過反射功能進行顯示, 如Object.getOwnPropertySymbols.

letMyClass=(function(){

// module scoped symbol

letkey=Symbol("key");

functionMyClass(privateData){

this[key]=privateData;

}

MyClass.prototype={

doStuff:function(){

// ...

this[key]

// ...

}

}

returnMyClass;

})();

letc=newMyClass("hello");

// c["key"] === undefined;

更多信息請參考MDN: Symbol

Subclassable Built-ins

在ES6中, 像Array, Date及DOM裡面的Element都可以被子類化(subclassed).

名為Ctor的函數的對象構造現在使用兩個階段(兩者都是實際派生的):

調用Ctor [@@create]分配對象,安裝任何特殊行為

調用新實例上的構造函數進行初始化

已知的@@create symbol可通過Symbol.create獲得。 內置函數現在顯式公開其@@create。

// Pseudo-code of Array

classArray{

constructor(...args){

/* ... */

}

static[Symbol.create](){

// Install special [[DefineOwnProperty]]

// to magically update length

}

}

// User code of Array subclass

classMyArrayextendsArray{

constructor(...args){

super(...args);

}

}

// Two-phase new :

// 1) Call @@create to allocate object

// 2) Invoke constructor on new instance

letarr=newMyArray();

arr[1]=12;

// arr.length === 2;

Math, Number, String, Array, Object APIs

新增了許多新的庫, 包括核心的Math庫, Array轉換助手, String助手以及用於copy的Object.assign.

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

[,,].fill(7,1);// [0, 7, 1]

[1,2,3].find(x=>x===3);// 3

[1,2,3].findIndex(x=>x===2);// 1

[1,2,3,4,5].copyWithin(3,);// [1, 2, 3, 1, 2]

["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:newPoint(,)});

Binary and Octal Literals 二進位和八進位

新添加兩個新的數字字面量格式: Binary(b)和Octal(o)

Promises

Promises是一個非同步編程庫. Promises是一個容器, 保存著某個未來才會結束的事件(通常是一個非同步操作)的結果. Promises已經在現在存在的JavaScript庫中被廣泛的使用.

functiontimeout(duration=){

returnnewPromise((resolve,reject)=>{

setTimeout(resolve,duration);

});

}

letp=timeout(1000).then(()=>{

returntimeout(2000);

}).then(()=>{

thrownewError("hmm");

}).catch(err=>{

returnPromise.all([timeout(100),timeout(200)]);

})

更多信息請參考MDN: Promise

Reflect API

Reflect對象與Proxy對象一樣,也是 ES6 為了操作對象而提供的新 API. 全反射API顯示了運行時(runtime-level)對象的元操作(meta-operations). 這實際上是Proxy API的逆向, 並允許進行與代理陷阱(proxy traps)相同的元操作(meta-operations)的調用.

請參考MDN: Reflect

Tail Calls 尾調用

指某個函數的最後一步是調用另一個函數. 尾部調用保證不會無限制地增長堆棧. 保證遞歸演算法面對無界輸入時的安全。

functionfactorial(n,acc=1){

use strict ;

if(n

returnacc;

}

returnfactorial(n-1,n*acc);

}

// Stack overflow in most implementations today,

// but safe on arbitrary inputs in ES6

factorial(100000);

關於本文

譯者:@池盛星

作者:@lukehoban

原文:https://github.com/lukehoban/es6features

點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 前端早讀課 的精彩文章:

從移動端click到搖一搖
你不應該錯過的前端技術會議
Nodejs cluster模塊深入探究
面向初學者的高階組件教程
構建高性能展開&收縮動畫

TAG:前端早讀課 |

您可能感興趣

181006《Give Me A Chance》MV預告的概念解析公開
經典大黃靴還能這樣玩!Timberland Construct 10061企劃亮相!
經典大黃靴還能這樣玩?!Timberland Construct 10061企劃亮相!
【20181006diy美甲教程】可愛俏皮蝴蝶香水
梵高日記20181006
NO.1006 劉小美一你是我的玫瑰花
【20181006美甲視頻】日系魔鏡粉水滴美甲
我國西部最重要的國防公路G219,全長10065公里
北川第1000個再生育家庭喜獲女嬰 系第1006個新生兒
中科院1006件專利今年首次拍賣
刺繡花朵圖案c1006的方法
中科院將拍賣1006件專利 創歷史新高
工信部擬收回中國網通10060客服碼號
【每日星運】塔羅占卜1006運勢,12星座運勢早知道!
【你求窩教-第1006期】油畫質感 浮雕花朵
比爾蓋茨身價1006億美元,但他打算只給每個孩子留1000萬美元
【20181006新款美甲】願你對過往的一切情深意重,但從不回頭。
日運1006 | 巨蟹疑慮消除;天蠍表現亮眼
官方緊急封禁1006個王者帳號:重點打擊高段位6排演員!
天美封停1006個王者賬號,原來是因為夢淚!