ECMAScript 6.0(如下簡稱ES6)是JavaScript語言的下一代標準,已經在2015年6月正式發佈了。它的目標,是使得JavaScript語言能夠用來編寫複雜的大型應用程序,成爲企業級開發語言。html
ES6與ECMAScript2015的關係git
ES6的第一個版本,就這樣在2015年6月發佈了,正式名稱就是《ECMAScript 2015標準》(簡稱ES2015)。,ES6既是一個歷史名詞,也是一個泛指,含義是5.1版之後的JavaScript的下一代標準,涵蓋了ES201五、ES201六、ES2017等等,而ES2015則是正式名稱,特指該年發佈的正式版本的語言標準。es6
因此,咱們能夠認爲ES6 = ES2015github
因爲不是目前全部的瀏覽器都能兼容ES6的所有特性,因此實際的項目仍是主要有ES5語法來開發。npm
這裏能夠看到 es6在各大瀏覽器的支持程度http://kangax.github.io/compat-table/es6/編程
可是ES6畢竟是之後的標準,並且約來越多的項目已經在用ES6開發了,你須要看懂別的人寫的代碼,同時讓本身寫的代碼讓別人看懂,最重要的是若是有天妹子問你,啥是ES6呀?數組
Babel是一個普遍使用的ES6轉碼器,能夠將ES6代碼轉爲ES5代碼,從而在現有環境執行。能夠去官網瞭解一下https://babeljs.io/瀏覽器
Babel作的事情很簡單,將ES6語法寫出的代碼,解析成ES5的語法,從而使得目前全部的瀏覽器都能正常運行。安全
好比:babel
// 轉碼前 input.map(item => item + 1); // 轉碼後 input.map(function (item) { return item + 1; });
能夠在babel官網上,在線查看ES6代碼轉換成ES5是什麼樣子的。
http://babeljs.io/repl/ 有時候不太穩定,可能須要翻一下 ┑( ̄Д  ̄)┍
在項目中使用babel須要配置.babelrc文件,存放在項目根目錄下。
先安裝 bable-cli
npm install babel-cli -g
而後安裝一個將es6編譯成es5的插件
npm install --save-dev babel-preset-es2015
將.babelrc中添加這個配置
{ "presets": ["es2015"], "plugins": [] }
而後運行
babel es6.js -o es5.js
就能夠看到es5.js就是解析事後的腳本
babel有大量的插件,還須要你們本身去了解。
let和const的用法都相似var。let是塊級做用域聲明,所聲明的變量,只在let所在的代碼塊內有效。
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
最爲典型的例子,for循環
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10
咱們每每須要使用閉包的手法來處理
var a = []; for (var i = 0; i < 10; i++) { (function(i){ a[i] = function () { console.log(i); }; })(i); } a[6](); //6
換成let會方便不少
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
變量提高問題
var聲明會存在變量提高的問題,若是變量在聲明前使用,其值則會輸出 undefined。let聲明則改變了這種奇怪的邏輯,let所聲明的變量必須先聲明,後使用,不然就會報錯。
// var 的狀況 console.log(foo); // undefined var foo = 2; // let 的狀況 console.log(bar); // ReferenceError let bar = 2;
不能重複聲明
和var不一樣,let不容許在相同做用域中,重複聲明同一個變量。
// 正常 function () { var a = 10; var a = 1; } // 報錯 function () { let a = 10; var a = 1; } // 報錯 function () { let a = 10; let a = 1; }
const用來聲明一個常量。一旦聲明,常量的值就不能改變。並且聲明後必須當即初始化賦值,不能後面賦值。
//報錯 const PI = 3.1415; PI // 3.1415 PI = 3; //報錯 const DOMAIN; DOMAIN = 'jd.com';
const和let很類似:1.只在塊級做用域中有效,2.不會提高變量,3.不能重複定義變量。
const聲明的變量雖然沒法改變,可是const命令只是保證所賦值的變量指向的地址不變,並不保證改地址的數據不變,因此當賦值的變量是一個值引用型的變量的時候,要格外的當心。
JavaScript語言的傳統方法是經過構造函數,定義並生成新對象。
function Human(name) { this.name = name; } Human.prototype.sayName = function () { return '(My name is' + this.name + )'; }; var zhang3 = new Human('zhang3'); var li4 = new Human('li4'); var wang5 = new Human('wang5');
ES6提供了更接近傳統語言(C++和Java)的寫法,引入了Class(類)這個概念,做爲對象的模板。經過class關鍵字,能夠定義類。基本上,ES6的class能夠看做只是一個語法糖,它的絕大部分功能,ES5均可以作到,新的class寫法只是讓對象原型的寫法更加清晰、更像面向對象編程的語法而已。上面的代碼用ES6的「類」改寫,就是下面這樣。
class Human { constructor(name) { this.name = name; } sayName() { return '(My name is' + this.name + )'; } } var zhang3 = new Human('zhang3'); var li4 = new Human('li4'); var wang5 = new Human('wang5');
constructor
constructor方法是類的默認方法,經過new命令生成對象實例時,自動調用該方法。一個類必須有constructor方法,若是沒有顯式定義,一個空的constructor方法會被默認添加。
constructor方法默認返回實例對象(即this),能夠指定返回另一個對象。
class Foo { constructor() { return Object.create(null); } } new Foo() instanceof Foo // false
extends
Class之間能夠經過extends關鍵字實現繼承,這比ES5的經過修改原型鏈實現繼承,要清晰和方便不少。
class Woman extends Human { constructor(name) { super(name); // 調用父類的constructor(name); this.sex = 'female'; } } let hanmeimei = new Woman('hanmeimei');
須要用函數表達式的地方,能夠用=>代替,代碼簡潔,並且綁定了this.
// bad [1, 2, 3].map(function (x) { return x * x; }); // good [1, 2, 3].map((x) => { return x * x; }); // best [1, 2, 3].map(x => x * x);
箭頭函數取代Function.prototype.bind
// bad const self = this; const boundMethod = function(...params) { return method.apply(self, params); } // acceptable const boundMethod = method.bind(this); // best const boundMethod = (...params) => method.apply(this, params);
ES6 容許按照必定模式,從數組和對象中提取值,對變量進行賦值,這被稱爲解構(Destructuring)。
沒明白啥意思,show me the code
數組解構賦值
// before let a = 1; let b = 2; let c = 3; //after let [a, b, c] = [1, 2, 3]; let [foo, [[bar], baz]] = [1, [[2], 3]]; let [ , , third] = ["foo", "bar", "baz"];
對象解構賦值
let { foo, bar } = { foo: "aaa", bar: "bbb" }; let { bar, foo } = { foo: "aaa", bar: "bbb" }; //變量名和屬性名若是不同,能夠這樣寫 var { foo: baz } = { foo: 'aaa', bar: 'bbb' };
字符串解構賦值
const [a, b, c, d, e] = 'hello';
還能夠對數值和布爾值,函數參數解構賦值。
Set
ES6 提供了新的數據結構 Set。它相似於數組,可是成員的值都是惟一的,沒有重複的值。
// 例一 var set = new Set([1, 2, 3, 4, 4]); [...set] // [1, 2, 3, 4] // 例二 var items = new Set([1, 2, 3, 4, 5, 5, 5, 5]); items.size // 5 // 例三 function divs () { return [...document.querySelectorAll('div')]; } var set = new Set(divs()); set.size // 56 // 相似於 divs().forEach(div => set.add(div)); set.size // 56
Map
JavaScript的對象(Object),本質上是鍵值對的集合(Hash結構),可是傳統上只能用字符串看成鍵。這給它的使用帶來了很大的限制。爲了解決這個問題,ES6提供了Map數據結構。它相似於對象,也是鍵值對的集合,可是「鍵」的範圍不限於字符串,各類類型的值(包括對象)均可以看成鍵。也就是說,Object結構提供了「字符串—值」的對應,Map結構提供了「值—值」的對應,是一種更完善的Hash結構實現。若是你須要「鍵值對」的數據結構,Map比Object更合適。
var m = new Map(); var o = {p: 'Hello World'}; m.set(o, 'content') m.get(o) // "content" m.has(o) // true m.delete(o) // true m.has(o) // false
傳統的JavaScript語言,輸出模板一般是這樣寫的。
$('#result').append( 'There are <b>' + basket.count + '</b> ' + 'items in your basket, ' + '<em>' + basket.onSale + '</em> are on sale!' );
ES6是這樣解決的
$('#result').append(` There are <b>${basket.count}</b> items in your basket, <em>${basket.onSale}</em> are on sale! `);
若是使用模板字符串表示多行字符串,全部的空格和縮進都會被保留在輸出之中。
$('#list').html(` <ul> <li>first</li> <li>second</li> </ul> `);
同時字符串模板中還能夠嵌入變量,變量能夠寫在${}裏面。
var x = 1; var y = 2; `${x} + ${y} = ${x + y}` // "1 + 2 = 3" `${x} + ${y * 2} = ${x + y * 2}` // "1 + 4 = 5" var obj = {x: 1, y: 2}; `${obj.x + obj.y}` // 3
字符串模板還支持嵌套
const tmpl = addrs => ` <table> ${addrs.map(addr => ` <tr><td>${addr.first}</td></tr> <tr><td>${addr.last}</td></tr> `).join('')} </table> `; const data = [ { first: '<Jane>', last: 'Bond' }, { first: 'Lars', last: '<Croft>' }, ]; console.log(tmpl(data)); // <table> // // <tr><td><Jane></td></tr> // <tr><td>Bond</td></tr> // // <tr><td>Lars</td></tr> // <tr><td><Croft></td></tr> // // </table>
在之前,咱們聲明瞭一個有不少參數的函數時,沒法直接指定默認值,全部會很不少default配置來處理。
function log(x, y) { y = y || 'World'; console.log(x, y); }
可是這種處理方法是不安全的,若是咱們這樣賦值
log('Hello') // Hello World log('Hello', 'China') // Hello China log('Hello', '') // Hello World
ES6 容許爲函數的參數設置默認值,即直接寫在參數定義的後面。
function log(x, y = 'World') { console.log(x, y); } log('Hello') // Hello World log('Hello', 'China') // Hello China log('Hello', '') // Hello
ES6 引入 rest 參數(形式爲「...變量名」),用於獲取函數的多餘參數,這樣就不須要使用arguments對象了。rest 參數搭配的變量是一個數組,該變量將多餘的參數放入數組中。
function add(...values) { let sum = 0; for (var val of values) { sum += val; } return sum; } add(2, 5, 3) // 10
擴展運算符 ...
它比如 rest 參數的逆運算,將一個數組轉爲用逗號分隔的參數序列。
console.log(...[1, 2, 3]) // 1 2 3 console.log(1, ...[2, 3, 4], 5) // 1 2 3 4 5 [...document.querySelectorAll('div')] // [<div>, <div>, <div>]
參考資料