本文參考瞭如下文章/PPT:javascript
以前的文章:html
1.關鍵字 Classjava
class Artist { constructor(name) { this.name = name; } perform() { return this.name + " performs "; } } class Singer extends Artist { constructor(name, song) { super.constructor(name); this.song = song; } perform() { return super.perform() + "[" + this.song + "]"; } } let james = new Singer("Etta James", "At last"); james instanceof Artist; // true james instanceof Singer; // true james.perform(); // "Etta James performs [At last]"
看上面例子就能明白。注意幾個關鍵字extends
,super
。git
雖然ES6的Class
本質上仍是語法糖,但這麼設計有它的目的。es6
在ES5中, function
關鍵字承擔着三個職責:github
constructor
,配合new
建立新對象。在ES6中,第2點被屬性方法定義(Method definitions)替代,第3點被Class關鍵字替代。一個關鍵字只承擔一個職責,再也不是滿屏function
,足夠清晰了吧?編程
有幾點要注意的:segmentfault
*
就能夠。constructor
,那會有個默認調用super的。2.繼承 Extendingpromise
繼承的幾種狀況和規則:瀏覽器
不要繼承空類, class Foo {}
,由於:
Function.prototype
(全部函數的原型都是這個)。Object.prototype
。繼承null:class Foo extends null {}
Function.prototype
。null
。繼承構造器:class Foo extends SomeClass
SomeClass
。SomeClass.prototype
。繼承非構造器(對象):class Foo extends SomeObject
Function.prototype
。SomeClass
。錯誤檢查:繼承的目標必定要是個對象或者null。若是是繼承構造器,那麼構造器的原型必定要是個對象或者null。
類聲明其實建立的是可變let綁定(binding,函數式編程會比較熟悉這個概念)。對於一個類Foo:
ES6的內置模塊系統借鑑了CommonJS和AMD各自的優勢:
不單單借鑑,ES6還對這些功能進行了優化:
1.語法
ES6模塊的導出出口形式有兩種:命名導出(一個模塊多個導出)、標準導出(一個模塊一個導出)。
命名導出 Named exports
//-------lib.js---------- export const sqrt = Math.sqrt; export function square(x) { return x * x; } export function diag(x, y) { return sqrt(square(x) + square(y)); } //-------main1.js-------- import { sqaure, diag } from 'lib'; console.log(square(11)); // 121 console.log(diag(3,4)); // 5 //或者這樣,命名導入的名稱: //-------main2.js-------- import * as lib from 'lib'; console.log(lib.square(11)); // 121 console.log(lib.diag(3,4)); // 5
標準導出 Default exports
//-------MyClass.js----- // 注意,`export`的操做對象是表達式,通常是沒有名字的。 export default class { ... }; //-------main3.js-------- // 經過模塊名字識別 import MyClass from 'MyClass'; let inst = new MyClass();
固然,這兩種導出也能夠混合使用。本質上,標準導出只是指名導出的一種,名稱是「default」而已。
就目前瞭解的來看,ES6的模塊導出貌似有些繁瑣,還不如CommonJS直接經過object
導出利索。
2.設計初衷 Design goals
TC39在討論ES6的模塊化問題時,主要考慮了下面幾點:
第一點就是要簡單已用。而靜態模塊結構更可能是出於性能優化、靜態類型檢查(沒錯,就是這個,動態語言爲何要有這個,其實仍是爲了性能)和之後的可能會加入的「宏模板」功能。
3.更多導入/導出寫法舉例
導入:
// 標準導入,命名導入 import theDefault, { named1, named2 } from 'src/mylib'; import theDefault from from 'src/mylib'; import { named1, named2 } from 'src/mylib'; // 重命名 import { named1 as myNamed1, named2 } from 'src/mylib'; // 將導入的模塊定義爲一個對象 // 模塊的每一個屬性都是該對象的同名方法屬性 import * as mylib from 'src/mylib'; // 僅讀取模塊,不導入任何功能 import 'src/mylib';
導出:
// 使用關鍵字**export**導出 export let myVar1 = ...; export function MyFunc() {...} export function* myGeneratorFunc() {...} // 也能夠以對象形式導出 const MY_CONST = ...; function myFunc() { ... } export { MY_CONST, myFunc } // 固然,名字不必定要相同 export { MY_CONST as THE_CONST, myFunc as theFunc }; // 支持重導出,即在當前模塊導出其餘模塊的功能 方便hack export * from 'src/other_module'; export { foo, bar } from 'src/other_module';
上面說的這些語法,普通的<script>
標籤是不支持的。ES6引入了一個<module>
標籤,負責載入模塊。<script>
標籤只能經過下面將要介紹的模塊API進行模塊載入。
4.模塊元數據
不單單是導入別的數據,ES6還能經過導入當前模塊拿到當前模塊的信息:
import { url } from this module; console.log(url);
這就像Ruby裏的____FILENAME____
。
5.模塊載入接口 Module loader API
API天然是爲了經過代碼控制模塊載入的,算是多少彌補了靜態結構靈活上上的缺陷。
每一個瀏覽器平臺都會有一個名爲System
的全局變量,經過這個變量調用相應接口,異步載入模塊(結合ES6的promises
):
System.import('some_module') .then(some_module => { ... }) .catch(error => { ... }) //固然也能夠一次載入多個模塊 Promise.all( ['module1', 'module2', 'module3'] ).map(x => Symtem.import(x))) .then(function([module1, module2, module3]) { ... });
其餘接口:
System.module(source, options?)
將source中的代碼求值成一個模塊。System.set(name, module)
註冊一個經過System.module
生成的模塊。System.define(name, source, options?)
前兩個接口的結合。更多關於模塊的說明
請看看Yehuda Katz的這一篇:Javascript Modules。