傳統的寫法javascript
function Point(x, y) { this.x = x this.y = y } Point.prototype.toString = () => { return `( ${this.x}, ${this.y} )` }
ES6爲了更接近面向對象的編程方式,提供了Class的概念java
class Point { constructor (x, y) { this.x = x this.y = y } toString { return `( ${this.x}, ${this.y} )` } }
上面定義了一個‘類’,一個構造方法constructor,this是實例對象,一個toString方法(注意沒有function這個保留字)編程
class類中的方法(除constructor以外)其實都定義在類的prototype屬性上函數
// 好比toString(),至關於 Point.prototype = { toString(){} } // 因此類的新方法能夠這樣添加進去 Object.assign(Point.prototype, { toString(){}, toValue(){} }) Point.prototype.constructor === Point // true
經過new命令生成對象實例時都默認自動調用constructor
方法,一個類必須有constructor
方法,沒有顯式定義的話,一個空的con
方法會被默認添加this
constructor () {}
該方法默認返回實例對象(就是this),可是能夠指定返回另外一個對象prototype
class Foo { constructor { return Object.create(null) } } new Foo() instanceof Foo // false
實例對象的建立同以前同樣code
class Point { // 這裏爲了縮小工做量,沒有所有書寫 constructor () {} tostring () {} } let point = new Point(2, 3) point.toString() // (2, 3) point.hasOwnProperty('x') // true,由於該實例屬性顯式的定義在this上 point.hasOwnProperty('toString') // false,由於方法都是定義在原型上的 point.prototype.hasOwnProperty('toString') // true point._proto_ === Point.prototype // true
ES6的Class只是ES5的構造函數的一層包裝,因此繼承了函數的許多屬性,包括name屬性對象
class Point {} Point.name // 'Point'
class不存在變量提高繼承
new Foo() // ReferenceError class Foo {} // let Foo = class {} // class Bar extends Foo {} // 由於class沒有提高,因此上面代碼不會報錯
class childPoint extends Point { constructor(x, y, color) { super(x, y) this.color = color } toString() { return this.color + '' + super.toString() // 等於Parent.toString() } }
子類必須在constructor方法中調用super方法,不然新建實例會出錯。另外只有調用super以後,纔可使用this關鍵字ip
class Point{} class childPoint extends Point{ constructor (x, y, color) { this.color = color // ReferenceError super(x, y) this.color = color // 正確 } } let cp = new childPoint() // ReferenceError
子類的_proto_屬性
class B extends A { } B._prototype_ === A // true B.prptotype._proto_ === A.prototype // true Object.getPrototypeof(B) === A // true
getter和setter
class MyClass { get prop() { return 'getter' } set prop(value) { console.log('setter:' + value ) } } let inst = new MyClass() inst.prop = 123 // setter: 123 inst.prop // 'getter'
Class的靜態方法,在一個方法前面,加上static關鍵字,就表示該方法不會被實例繼承,可是能夠被子類繼承
class Foo { static classMethod () { return 'hello' } } Foo.classMethod() // hello let foo = new Foo() foo.classMethod() // TypeError: undefined is not a function // 可是能夠被子類繼承,也可從super上調用 class Bar extends Foo { // static classMethod() { // return super.classMethod() + ', too' // } } Bar.classMethod() // hello