ECMAScript 6(如下簡稱ES6)是JavaScript語言的下一代標準。由於當前版本的ES6是在2015年發佈的,因此又稱ECMAScript 2015。
也就是說,ES6就是ES2015。
目前並非全部瀏覽器都能兼容ES6所有特性,咱們可使用Babel工具來轉換成es5
Babel是一個普遍使用的ES6轉碼器,能夠將ES6代碼轉爲ES5代碼html
最經常使用的ES6特性
let, const, class, extends, super, arrow functions, template string, destructuring, default, rest argumentses6
一、let用法相似於var,可是所聲明的變量,只在let命令所在的代碼塊內有效
二、不存在變量提高,let不像var那樣會發生「變量提高」現象。因此,變量必定要在聲明後使用,不然報錯。segmentfault
console.log(foo); // 輸出undefined console.log(bar); // 報錯ReferenceError var foo =2;let bar =2;
三、在let和const之間,建議優先使用const,尤爲是在全局環境,不該該設置變量,只應設置常量。瀏覽器
const聲明常量還有兩個好處,一是閱讀代碼的人馬上會意識到不該該修改這個值,二是防止了無心間修改變量值所致使的錯誤。服務器
四、ES6明確規定,若是區塊中存在let和const命令,這個區塊對這些命令聲明的變量,從一開始就造成了封閉做用域。凡是在聲明以前就使用這些變量,就會報錯。
總之,在代碼塊內,使用let命令聲明變量以前,該變量都是不可用的。也就是「暫時性死區」。app
JavaScript一直沒有模塊(module)體系,沒法將一個大程序拆分紅互相依賴的小文件,再用簡單的方法拼裝起來。其餘語言都有這項功能,好比Ruby的require、Python的import,甚至就連CSS都有@import,可是JavaScript任何這方面的支持都沒有,這對開發大型的、複雜的項目造成了巨大障礙。函數
這有可能致使兩個問題:工具
在ES6以前,社區制定了一些模塊加載方案,最主要的有CommonJS和AMD兩種。前者用於服務器,後者用於瀏覽器。ES6在語言規格的層面上,實現了模塊功能,並且實現得至關簡單,徹底能夠取代現有的CommonJS和AMD規範,成爲瀏覽器和服務器通用的模塊解決方案。優化
傳統的寫法
首先咱們回顧下require.js的寫法。假設咱們有兩個js文件: index.js和content.js,如今咱們想要在index.js中使用content.js返回的結果,咱們要怎麼作呢?
首先定義:ui
//content.js define('content.js', function(){ return'A cat'; })
而後require:
//index.js require(['./content.js'], function(animal){ console.log(animal); //A cat })
CommonJS寫法
//index.js var animal = require('./content.js') //content.js module.exports = 'A cat'
ES6的寫法
//index.js import animal from'./content'//content.js export default'A cat'
// ES6模塊
import { stat, exists, readFile } from 'fs';
上面代碼的實質是從fs模塊加載3個方法,其餘方法不加載。這種加載稱爲「編譯時加載」,即ES6能夠在編譯時就完成模塊加載,效率要比CommonJS模塊的加載方式高。固然,這也致使了無法引用ES6模塊自己,由於它不是對象。
瀏覽器使用ES6模塊的語法以下。
<script type="module" src="foo.js"></script>
上面代碼在網頁中插入一個模塊foo.js,因爲type屬性設爲module,因此瀏覽器知道這是一個ES6模塊。
Node的默認模塊格式是CommonJS,目前還沒決定怎麼支持ES6模塊。因此,只能經過Babel這樣的轉碼器,在Node裏面使用ES6模塊。
ES6的模塊自動採用嚴格模式,無論你有沒有在模塊頭部加上"use strict";。
一、export命令
模塊功能主要由兩個命令構成:export和import。export命令用於規定模塊的對外接口,import命令用於輸入其餘模塊提供的功能。
一個模塊就是一個獨立的文件。該文件內部的全部變量,外部沒法獲取。若是你但願外部可以讀取模塊內部的某個變量,就必須使用export關鍵字輸出該變量。例如,
// profile.js export var firstName ='Michael'; export var lastName ='Jackson'; export var year =1958;
也能夠是下面這種寫法(優先考慮使用),
// profile.js var firstName ='Michael';var lastName ='Jackson';var year =1958; export {firstName, lastName, year};
export命令除了輸出變量,還能夠輸出函數或類(class)。
export function multiply(x, y){return x * y;};
可使用as關鍵字重命名
function v1(){...} function v2(){...} export { v1 as streamV1, v2 as streamV2, v2 as streamLatestVersion };
注意:export命令能夠出如今模塊的任何位置,只要處於模塊頂層就能夠。若是處於塊級做用域內,就會報錯,import命令也是如此,這是由於處於條件代碼塊之中,就無法作靜態優化了,違背了ES6模塊的設計初衷。下面代碼中,export語句放在函數之中,結果報錯。
function foo(){ export default 'bar' // SyntaxError } foo()
二、import命令
使用export命令定義了模塊的對外接口之後,其餘JS文件就能夠經過import命令加載這個模塊(文件)。
import {firstName, lastName, year} from './profile';
上面代碼的import命令,就用於加載profile.js文件,並從中輸入變量。import命令接受一個對象(用大括號表示),裏面指定要從其餘模塊導入的變量名
使用as關鍵字將輸入的變量從新命名
import { lastName as surname } from './profile';
import命令具備提高效果,會提高到整個模塊的頭部,首先執行。
foo(); import { foo } from 'my_module';
上面的代碼不會報錯,由於import的執行早於foo的調用。
import語句會執行所加載的模塊,可是不輸入任何值。
import 'lodash';
import 也能夠引用文件夾/目錄
如import router from './router'
這裏router是個目錄 裏面有個index.js文件
三、模塊總體加載
circle模塊有2個方法
// circle.js export function area(radius){return Math.PI * radius * radius;} export function circumference(radius){return2* Math.PI * radius;} 經過使用*號加載整個模塊 import * as circle from './circle'; console.log('圓面積:'+ circle.area(4)); console.log('圓周長:'+ circle.circumference(14));
一、class的基本用法
ES6提供了更接近傳統語言的寫法,引入了Class(類)這個概念,做爲對象的模板。經過class關鍵字,能夠定義類
//定義類 class Point{ constructor(x, y){ this.x = x; this.y = y; } toString(){ return'('+this.x +', '+this.y +')'; } }
constructor這就是構造方法,而this關鍵字則表明實例對象
定義「類」的方法的時候,前面不須要加上function這個關鍵字,直接把函數定義放進去了就能夠了。另外,方法之間不須要逗號分隔,加了會報錯。
使用時直接對類使用new命令
class Bar{ doStuff(){ console.log('stuff'); } } var b =new Bar(); b.doStuff() // "stuff"
二、constructor構造方法
constructor方法是類的默認方法,經過new命令生成對象實例時,自動調用該方法。一個類必須有constructor方法,若是沒有顯式定義,一個空的constructor方法會被默認添加。
constructor(){}
三、class表達式
與函數同樣,類也可使用表達式的形式定義。
const MyClass = class Me{ getClassName(){ return Me.name; } };
這個類的名字是MyClass而不是Me,Me只在Class的內部代碼可用,指代當前類。
若是類的內部沒用到的話,能夠省略Me
const MyClass = class {/* ... */};
採用Class表達式,能夠寫出當即執行的Class。
let person =newclass{ constructor(name){ this.name = name; } sayName(){ console.log(this.name); } }('張三'); person.sayName(); // "張三"
四、class類繼承
經過extends關鍵字實現繼承
class ColorPoint extends Point{}
function(i){ return i + 1; } //ES5 (i) => i + 1//ES6
若是方程比較複雜,則須要用{}把代碼包起來:
function(x, y){ x++; y--; return x + y; } (x, y) => { x++; y--; return x+y }
在對象方法中使用this
傳統的寫法須要將this傳給self,再用self來指代this
says(say){ var self = this; setTimeout(function(){ console.log(self.type + ' says ' + say) }, 1000)
使用es6的寫法
classAnimal { constructor(){ this.type = 'animal' } says(say){ setTimeout( () => { console.log(this.type + ' says ' + say) }, 1000) } } var animal = new Animal() animal.says('hi') //animal says hi
當咱們使用箭頭函數時,函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。並非由於箭頭函數內部有綁定this的機制,實際緣由是箭頭函數根本沒有本身的this,它的this是繼承外面的,所以內部的this就是外層代碼塊的this。
當咱們要插入大段的html內容到文檔中時,傳統的寫法很是麻煩,因此以前咱們一般會引用一些模板工具庫,好比mustache等等
$("#result").append( "There are <b>" + basket.count + "</b> " + "items in your basket, " + "<em>" + basket.onSale + "</em> are on sale!" );
咱們要用一堆的'+'號來鏈接文本與變量,而使用ES6的新特性模板字符串`後 ``` $("#result").append(
There are ${basket.count} items
in your basket, ${basket.onSale}
are on sale!
); ``` 用反引號(\)來標識起始,用${}
來引用變量,並且全部的空格和縮進都會被保留在輸出之中
default很簡單,意思就是默認值,調用animal()方法時忘了傳參數,傳統的作法就是加上這一句type = type || 'cat' 來指定默認值
function animal(type){ type = type || 'cat' console.log(type) } animal()
用ES6咱們而已直接這麼寫:
function animal(type = 'cat'){ console.log(type) } animal()
rest語法也很簡單,看例子:
function animals(...types){ console.log(types) } animals('cat', 'dog', 'fish') //["cat", "dog", "fish"]
https://segmentfault.com/a/1190000004365693#articleHeader7 http://es6.ruanyifeng.com/