ECMAScript 6

ES6簡介

ECMAScript 6(以下簡稱ES6)是JavaScript語言的下一代標(biāo)準(zhǔn),于2015年6月批準(zhǔn)通過。ECMAScript6的目標(biāo)葵姥,是使得JavaScript語言可以用來編寫復(fù)雜的大型應(yīng)用程序紊浩,成為企業(yè)級(jí)開發(fā)語言。讓代碼更加準(zhǔn)確酌呆,更易于閱讀衡载。

ECMAScript是JavaScript語言的國際標(biāo)準(zhǔn),JavaScript是ECMAScript的實(shí)現(xiàn)(ES是規(guī)范肪笋,JS是實(shí)現(xiàn))月劈。在日常場(chǎng)合度迂,這兩個(gè)詞是可以互換的。

環(huán)境支持

目前還沒有任何一款瀏覽器支持ES6特性

支持程度

Firefox 49支持93%猜揪;Chrome 52支持98%

Node.js對(duì)ES6的支持度比瀏覽器更高

ES6 to ES5轉(zhuǎn)換器

Traceur轉(zhuǎn)碼器

Traceur允許將ES6代碼直接插入網(wǎng)頁

(1)在網(wǎng)頁頭部加載Traceur庫文件

(2)script標(biāo)簽的type屬性的值是module惭墓,而不是text/javascript,編譯器會(huì)自動(dòng)將所有type=module的代碼編譯為ES5而姐,然后再交給瀏覽器執(zhí)行

<!DOCTYPE html>
<html>
  <head>
    <title>Hello, World!</title>
    <script src="traceur.js"></script>
    <script src="BrowserSystem.js"></script>
    <script src="bootstrap.js"></script>
  </head>
  <body>
    <script type="module">
      class Greeter {
        constructor(message) {
          this.message = message;
        }
        greet() {
          let element = document.querySelector('#message');
          element.textContent = this.message;
        }
      }
      let greeter = new Greeter('Hello World!');
      greeter.greet();
    </script>
    <h1 id="message"></h1>
  </body>
</html>

Babel轉(zhuǎn)碼器

Babel可以將ES6代碼轉(zhuǎn)為ES5代碼腊凶;得益于強(qiáng)大的Babel的存在,使我們可以方便的使用ES6的語法拴念,而不必考慮瀏覽器支持的問題钧萍。

// 轉(zhuǎn)碼前
input.map(item => item + 1);

// 轉(zhuǎn)碼后
input.map(function (item) {
  return item + 1;
});

ES6特性

新語法

let和const

let聲明變量,只在let命令所在的代碼塊內(nèi)有效

為什么需要塊級(jí)作用域政鼠?

1风瘦、內(nèi)層變量可能會(huì)覆蓋外層變量

var tmp = new Date();

function f() {
  console.log(tmp);
  if (false) {
    var tmp = "hello world";
  }
}

f(); // undefined

2、用來計(jì)數(shù)的循環(huán)變量泄露為全局變量

var s = 'hello';

for (var i = 0; i < s.length; i++) {
  console.log(s[i]);
}

console.log(i); // 5

const聲明常量公般,只在聲明所在的塊級(jí)作用域內(nèi)有效

const PI = 3.1415;
PI // 3.1415

PI = 3;
// TypeError: Assignment to constant variable.

if (true) {
  const MAX = 5;
}

MAX // Uncaught ReferenceError: MAX is not defined

嘗試去改變用 const 聲明的常量時(shí)万搔,就會(huì)報(bào)錯(cuò)

引用第三方庫的時(shí)聲明的變量,用 const 來聲明可以避免未來不小心重命名而導(dǎo)致出現(xiàn)bug

const monent = require('moment')

解構(gòu)賦值(Destructuring)

從數(shù)組和對(duì)象中提取值官帘,對(duì)變量進(jìn)行賦值瞬雹。本質(zhì)上,這種寫法屬于“模式匹配”刽虹,只要等號(hào)兩邊的模式相同酗捌,左邊的變量就會(huì)被賦予對(duì)應(yīng)的值。

var a = 1;
var b = 2;
var c = 3;
寫成
var [a, b, c] = [1, 2, 3];

//提取值
var jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};

let { id, status, data: number } = jsonData;

console.log(id, status, number);
// 42, "OK", [867, 5309]

//遍歷Map結(jié)構(gòu)

var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for (let [key, value] of map) {
  console.log(key + " is " + value);
}
// first is hello
// second is world

箭頭函數(shù)(Fat arrow functions)

允許使用 => 定義函數(shù)涌哲,箭頭函數(shù)自動(dòng)綁定當(dāng)前上下文 this胖缤,更簡潔的語法和與父作用域共享關(guān)鍵字this

var f = v => v;
//等同于
var f = function(v) {
  return v;
};
function getVerifiedToken(selector) {
  return getUsers(selector)
    .then(function (users) { return users[0]; })
    .then(verifyUser)
    .then(function (user, verifiedToken) { return verifiedToken; })
    .catch(function (err) { log(err.stack); });
}

使用箭頭函數(shù)

function getVerifiedToken(selector) {
  return getUsers(selector)
    .then(users => users[0])
    .then(verifyUser)
    .then((user, verifiedToken) => verifiedToken)
    .catch(err => log(err.stack));
}
  • function{}都消失了,所有的回調(diào)函數(shù)都只出現(xiàn)在了一行里膛虫。

  • 當(dāng)只有一個(gè)參數(shù)時(shí)草姻,()也消失了(rest參數(shù)是一個(gè)例外,如(...args) => ...)稍刀。

  • 當(dāng){}消失后撩独,return關(guān)鍵字也跟著消失了。單行的箭頭函數(shù)會(huì)提供一個(gè)隱式的return账月。

胖箭頭函數(shù)不產(chǎn)生屬于它自己上下文的this

$('.current-time').each(function () {
  var self = this;
 
  setInterval(function () {
    $(self).text(Date.now());
  }, 1000);
});
$('.current-time').each(function () {
  setInterval(() => $(this).text(Date.now()), 1000);
});

生成器(Generator)

Generator 是一種可以停止并在之后重新進(jìn)入的函數(shù)综膀。生成器的環(huán)境(綁定的變量)會(huì)在每次執(zhí)行后被保存,下次進(jìn)入時(shí)可繼續(xù)使用局齿。function關(guān)鍵字后面有個(gè)*號(hào)剧劝,函數(shù)體內(nèi)可以使用yield語句進(jìn)行流程控制。

function* gen() {
  yield 'hello';
  yield 'world';
  return true;
}

var iter = gen();

iter.next()
// { value: 'hello', done: false }

iter.next()
// { value: 'world', done: false }

iter.next()
// { value: undefined, done: true }

使用for...of語句時(shí)不需要使用next方法

function* fibonacci() {
  let [prev, curr] = [0, 1];
  for (;;) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (let n of fibonacci()) {
  if (n > 1000) break;
  console.log(n);
}

遍歷器(Iterator)

Iterator是一種接口抓歼,為各種不同的數(shù)據(jù)結(jié)構(gòu)提供統(tǒng)一的訪問機(jī)制讥此。任何數(shù)據(jù)結(jié)構(gòu)只要部署Iterator接口拢锹,就可以完成遍歷操作(即依次處理該數(shù)據(jù)結(jié)構(gòu)的所有成員)

  1. 是為各種數(shù)據(jù)結(jié)構(gòu),提供一個(gè)統(tǒng)一的萄喳、簡便的訪問接口卒稳;

  2. 是使得數(shù)據(jù)結(jié)構(gòu)的成員能夠按某種次序排列;

  3. Iterator接口主要供for...of使用

使用TypeScript的寫法他巨,遍歷器接口(Iterable)充坑、指針對(duì)象(Iterator)和next方法返回值的規(guī)格可以描述如下

interface Iterable {
  [Symbol.iterator]() : Iterator,
}

interface Iterator {
  next(value?: any) : IterationResult,
}

interface IterationResult {
  value: any,
  done: boolean,
}

修飾器(Decorator)

修飾器(Decorator)是一個(gè)函數(shù),用來修改類的行為染突。這是ES7的一個(gè)提案捻爷,目前Babel轉(zhuǎn)碼器已經(jīng)支持。修飾器對(duì)類的行為的改變份企,是代碼編譯時(shí)發(fā)生的也榄,而不是在運(yùn)行時(shí)

@decorator
class A {}

// 等同于

class A {}
A = decorator(A) || A;

其他特性

  1. Symbol數(shù)據(jù)類型

  2. Set和Map數(shù)據(jù)結(jié)構(gòu)

  3. 異步操作和Async函數(shù)

  4. Proxy和Reflect

  5. 二進(jìn)制數(shù)組

  6. Promise對(duì)象

標(biāo)準(zhǔn)庫擴(kuò)展

  1. 字符串的擴(kuò)展

  2. 函數(shù)的擴(kuò)展

  3. 數(shù)值的擴(kuò)展

  4. 數(shù)組的擴(kuò)展

  5. 對(duì)象的擴(kuò)展

字符串?dāng)U展-模板字符串

$('#result').append(
  'There are <b>' + basket.count + '</b> ' +
  'items in your basket, ' +
  '<em>' + basket.onSale +
  '</em> are on sale!'
);
$('#result').append(`
  There are <b>${basket.count}</b> items
   in your basket, <em>${basket.onSale}</em>
  are on sale!
`);

函數(shù)擴(kuò)展-函數(shù)默認(rèn)值

在ES6之前,不能直接為函數(shù)的參數(shù)指定默認(rèn)值司志,只能采用變通的方法手蝎,ES6允許為函數(shù)的參數(shù)設(shè)置默認(rèn)值,即直接寫在參數(shù)定義的后面俐芯。

function log(x){
    x = x || 'hello'  
    console.log(x)
}
log()
function log(x = 'hello'){
    console.log(type)
}
log()

函數(shù)擴(kuò)展-rest參數(shù)

ES6引入rest參數(shù)(形式為“...變量名”),用于獲取函數(shù)的多余參數(shù)钉鸯。rest參數(shù)之后不能再有其他參數(shù)(即只能是最后一個(gè)參數(shù))吧史。

function add(...types){
    console.log(types)
}
add('a', 'b', 'c') //["a", "b", "c"]

面向?qū)ο蠛湍K化

Class

JavaScript語言的傳統(tǒng)方法是通過構(gòu)造函數(shù),定義并生成新對(duì)象唠雕。寫法跟傳統(tǒng)的面向?qū)ο笳Z言差異很大贸营。

類的繼承,Class 之間可以通過extends關(guān)鍵字實(shí)現(xiàn)繼承岩睁,這比ES5的通過修改原型鏈實(shí)現(xiàn)繼承钞脂,要清晰和方便很多

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

var p = new Point(1, 2);
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}
class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y); // 調(diào)用父類的constructor(x, y)
    this.color = color;
  }

  toString() {
    return this.color + ' ' + super.toString(); // 調(diào)用父類的toString()
  }
}

super關(guān)鍵字

(1)作為函數(shù)調(diào)用時(shí)(即super(...args)),super代表父類的構(gòu)造函數(shù)捕儒。

(2)作為對(duì)象調(diào)用時(shí)(即super.prop或super.method())冰啃,super代表父類

模塊化

import、export

  1. 語言層級(jí)支持刘莹,無需引入第三方庫阎毅,不再引用seajs和requirejs就能使用模塊

  2. 統(tǒng)一的API,使用保留關(guān)鍵字 import 和 export 点弯,從而在瀏覽器實(shí)現(xiàn)后能最大程度的向下兼容

  3. 精簡語法扇调、唯一導(dǎo)出出口(single exports)和循環(huán)依賴(cyclic dependencies)的特點(diǎn)

  4. 支持結(jié)構(gòu)的靜態(tài)分析(靜態(tài)檢查,優(yōu)化等等)

// a.js如下
import {bar} from './b.js';
console.log('a.js');
console.log(bar);
export let foo = 'foo';

// b.js
import {foo} from './a.js';
console.log('b.js');
console.log(foo);
export let bar = 'bar';

babel-node a.js
//結(jié)果
b.js
undefined
a.js
bar

由于a.js的第一行是加載b.js抢肛,所以先執(zhí)行的是b.js狼钮。而b.js的第一行又是加載a.js碳柱,這時(shí)由于a.js已經(jīng)開始執(zhí)行了,所以不會(huì)重復(fù)執(zhí)行熬芜,而是繼續(xù)往下執(zhí)行b.js莲镣,所以第一行輸出的是b.js。

接著猛蔽,b.js要打印變量foo剥悟,這時(shí)a.js還沒執(zhí)行完,取不到foo的值曼库,導(dǎo)致打印出來是undefined区岗。b.js執(zhí)行完,開始執(zhí)行a.js毁枯,這時(shí)就一切正常了慈缔。

ES6應(yīng)用

組件框架轉(zhuǎn)向 ES6開發(fā)

angular2

react

Aurelia

...

總結(jié)

  • Let和Const更加準(zhǔn)確

  • 解構(gòu)和箭頭函數(shù)更加精簡

  • 標(biāo)準(zhǔn)庫擴(kuò)展

  • 借鑒其他語言實(shí)現(xiàn)生成器、遍歷器等

  • Promise將最佳實(shí)踐標(biāo)準(zhǔn)化

  • Module / Class 等讓 JS 更適合大型編程

參考

ECMAScript 6入門

[譯]JavaScript ES6箭頭函數(shù)指南

ECMAScript 6新特性印象之二:面對(duì)對(duì)象和模塊化

es6-js-future

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末种玛,一起剝皮案震驚了整個(gè)濱河市藐鹤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赂韵,老刑警劉巖娱节,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異祭示,居然都是意外死亡肄满,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門质涛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來稠歉,“玉大人,你說我怎么就攤上這事汇陆∨ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵毡代,是天一觀的道長阅羹。 經(jīng)常有香客問我,道長教寂,這世上最難降的妖魔是什么灯蝴? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮孝宗,結(jié)果婚禮上穷躁,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好问潭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布猿诸。 她就那樣靜靜地躺著,像睡著了一般狡忙。 火紅的嫁衣襯著肌膚如雪梳虽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天灾茁,我揣著相機(jī)與錄音窜觉,去河邊找鬼。 笑死北专,一個(gè)胖子當(dāng)著我的面吹牛禀挫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拓颓,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼语婴,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了驶睦?” 一聲冷哼從身側(cè)響起砰左,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎场航,沒想到半個(gè)月后缠导,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡溉痢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年酬核,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片适室。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖举瑰,靈堂內(nèi)的尸體忽然破棺而出捣辆,到底是詐尸還是另有隱情,我是刑警寧澤此迅,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布汽畴,位于F島的核電站,受9級(jí)特大地震影響耸序,放射性物質(zhì)發(fā)生泄漏忍些。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一坎怪、第九天 我趴在偏房一處隱蔽的房頂上張望罢坝。 院中可真熱鬧,春花似錦搅窿、人聲如沸嘁酿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闹司。三九已至娱仔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間游桩,已是汗流浹背牲迫。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留借卧,地道東北人盹憎。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像谓娃,于是被迫代替她去往敵國和親脚乡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容