本文摘自ECMAScript6入門,轉載請註明出處。es6
1、類(Class)編程
1.基本語法數組
JavaScript語言的傳統方法是經過構造函數,定義並生成新對象。下面是一個例子數據結構
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);
ES6提供了更接近傳統語言的寫法,引入了Class(類)這個概念,做爲對象的模板。經過class
關鍵字,能夠定義類。基本上,ES6的class
能夠看做只是一個語法糖,它的絕大部分功能,ES5均可以作到,新的class
寫法只是讓對象原型的寫法更加清晰、更像面向對象編程的語法而已。上面的代碼用ES6的「類」改寫,就是下面這樣。函數
//定義類 class Point { constructor(x, y) { //constructor 構造方法 this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } }
var p = new Point(1, 2);
構造函數的prototype
屬性,在ES6的「類」上面繼續存在。事實上,類的全部方法都仍是定義在類的prototype
屬性上面。this
2.constructor方法spa
constructor
方法是類的默認方法,經過new
命令生成對象實例時,自動調用該方法。一個類必須有constructor
方法,若是沒有顯式定義,一個空的constructor
方法會被默認添加。prototype
2、繼承(Extends)code
Class之間能夠經過extends
關鍵字實現繼承,這比ES5的經過修改原型鏈實現繼承,要清晰和方便不少。對象
class ColorPoint extends Point { constructor(x, y, color) { super(x, y); // 調用父類的constructor(x, y) this.color = color; } toString() { return this.color + ' ' + super.toString(); // 調用父類的toString() } }
上面代碼中,constructor
方法和toString
方法之中,都出現了super
關鍵字,它在這裏表示父類的構造函數,用來新建父類的this
對象。
子類必須在constructor
方法中調用super
方法,不然新建實例時會報錯。這是由於子類沒有本身的this
對象,而是繼承父類的this
對象,而後對其進行加工。若是不調用super
方法,子類就得不到this
對象。
3、原生構造函數繼承
原生構造函數是指語言內置的構造函數,一般用來生成數據結構。ECMAScript的原生構造函數大體有下面這些。之前,這些原生構造函數是沒法繼承的。
ES6容許繼承原生構造函數定義子類,由於ES6是先新建父類的實例對象this
,而後再用子類的構造函數修飾this
,使得父類的全部行爲均可以繼承。下面是一個繼承Array
的例子。
class MyArray extends Array { constructor(...args) { super(...args); } } var arr = new MyArray(); arr[0] = 12; arr.length // 1 arr.length = 0; arr[0] // undefined
上面代碼定義了一個MyArray
類,繼承了Array
構造函數,所以就能夠從MyArray
生成數組的實例。這意味着,ES6能夠自定義原生數據結構(好比Array、String等)的子類,這是ES5沒法作到的。
4、Class的Generator方法
若是某個方法以前加上星號(*
),就表示該方法是一個Generator函數。
class Foo { constructor(...args) { this.args = args; } * [Symbol.iterator]() { for (let arg of this.args) { yield arg; } } } for (let x of new Foo('hello', 'world')) { console.log(x); } // hello // world
上面代碼中,Foo類的Symbol.iterator方法前有一個星號,表示該方法是一個Generator函數。Symbol.iterator方法返回一個Foo類的默認遍歷器,for...of循環會自動調用這個遍歷器。
5、Class的靜態方法
類至關於實例的原型,全部在類中定義的方法,都會被實例繼承。若是在一個方法前,加上static
關鍵字,就表示該方法不會被實例繼承,而是直接經過類來調用,這就稱爲「靜態方法」。
class Foo { static classMethod() { return 'hello'; } } Foo.classMethod() // 'hello' var foo = new Foo(); foo.classMethod() // TypeError: foo.classMethod is not a function
上面代碼中,Foo
類的classMethod
方法前有static
關鍵字,代表該方法是一個靜態方法,能夠直接在Foo
類上調用(Foo.classMethod()
),而不是在Foo
類的實例上調用。若是在實例上調用靜態方法,會拋出一個錯誤,表示不存在該方法。
父類的靜態方法,能夠被子類繼承。
class Foo { static classMethod() { return 'hello'; } } class Bar extends Foo { } Bar.classMethod(); // 'hello'
上面代碼中,父類Foo
有一個靜態方法,子類Bar
能夠調用這個方法。