es6的class實際上是構造函數的語法糖,可是又有區別,下面來詳細分析下classjavascript
先來看下class的定義的代碼java
class Point{ constructor(){} toString(){} } var p = new Point() p.constructor === Point.prototype.contructor//true Object.keys(Point.prototype)//[] Object.getOwnPropertyNames(Point.prototype)//['constructor','toString']
子類必須在constructor中調用super方法,不然新建實例會報錯,由於子類沒有本身的this,而是繼承了父類的this,這和es5中的繼承不同,
由於es5中的繼承是先創造子類的實例對象this,再將父類的方法添加到this上(parent.call(this)),es6中是先繼承父類的實例對象this,而後再用子類的構造函數修改this。若是子類沒有定義constructor,那麼這個方法會被默認添加。
在子類的構造函數中,只有調用super關鍵字以後,纔可以使用this關鍵字,不然會報錯,由於子類實例的構建基於對父類實例的加工,只有super方法才能返回父類的實例。es6
prototype和__proto__
大多數瀏覽器的es5實現中,每個對象都有__proto__屬性(IE8除外),指向對應的構造函數的prototype屬性。class做爲構造函數的語法糖,同時有prototype屬性和__proto__屬性,由於存在兩條繼承鏈。瀏覽器
若是在一個方法前加上static關鍵字,就表示該方法不會被實例繼承,而是直接經過類調用,成爲‘靜態方法’。
看下代碼數據結構
class Foo{ static classMethod(){} } Foo.classMethod(); class Bar extends Foo(){ static classMethod(){ return super.classMethod() } } Bar.classMethod();
上面Foo類有靜態方法classMethod,只能經過Foo.classMethod調用,不可經過實例調用,不然會報錯,父類的靜態方法可被子類繼承。函數
靜態屬性是指class自己的屬性,即class.propname,而不是定義在實例對象(this)上的屬性。this
class Foo{} Foo.prop = 1; Foo.prop //1
上面的方法能夠讀、寫Foo類的靜態屬性prop,可是es6中規定,class中只有靜態方法,沒有靜態屬性es5
es6爲new命令引入了new.target屬性,返回new命令所做用的構造函數,若是構造函數不是經過new命令調用的,那麼new.target會返回undefined,所以這個屬性能夠判斷構造函數是如何被調用的prototype