JavaScript傳統的定義構造函數的定義方式是以下:javascript
function Point(x,y){ this.x = x; this.y = y; } Point.prototype.toString = function () { return '(' + this.x + ', ' + this.y + ')'; }; let p = new Point(1,2); console.log(p)
運行結果:java
ES6裏面經過類這樣表示:編程
class Point{ constructor(x,y){ this.x = x; this.y = y; } toString(){ return '('+this.x+','+this.y+')'; } } let p = new Point(1,2); console.log(p)
運行結果:函數
經過上面的代碼能夠看出ES6裏面經過class關鍵字定義的類實際上是語法糖而已,其中絕大多數功能ES5裏面已經實現過了,只不過ES6裏面的class讓對象原型的寫法更加清晰,更像面向對象編程的寫法而已。
上面定義的「類」裏面,能夠看出來有一個constructor方法,這就是構造方法。裏面還有this關鍵字表明瞭實例對象。也就是說ES5裏面的構造函數,就是ES6裏面的類裏面的構造方法。
Point類裏面還有一個方法叫toString,注意「類」裏面定義方法的時候不用加function關鍵字,直接把方法定義寫進去就好了。還有一點就是方法之間不用加逗號了,若是加了會報錯的。this
class Point { // ... } typeof Point // "function" Point === Point.prototype.constructor // true
類的數據類型是函數,類自己指的就是構造函數spa
function Point(){ // ... } console.log(Point === Point.prototype.constructor);//true
ES6裏面的類,徹底能夠說是構造函數的另外一種寫法。prototype
class Bar { doStuff() { console.log('stuff'); } } var b = new Bar(); b.doStuff() // "stuff"
使用的時候,也是直接對類使用new命令,跟構造函數的用法徹底一致。code
構造函數的prototype屬性,ES6「類」裏面依然存在的,類裏面定義的全部的方法,其實都添加到類的prototype屬性裏面。對象
class Point { constructor() { // ... } toString() { // ... } toValue() { // ... } } // 等同於 Point.prototype = { constructor() {}, toString() {}, toValue() {}, };
在類的實例上面調用方法,其實就是調用原型上的方法。ip
class Point { constructor() { // ... } toString() { // ... } toValue() { // ... } } let p = new Point(); console.log(p.toString === Point.prototype.toString);//true
constructor方法是類的默認方法,經過new命令生成對象實例時,自動調用該方法。一個類必須有constructor方法,若是沒有顯式定義,一個空的constructor方法會被默認添加。
class Point { } // 等同於 class Point { constructor() {} }
類經過new關鍵字實例化的時候默認自動調用constructor構造方法,constructor構造方法返回一個類實例(即this對象)
ES6類裏面實例化對象,跟ES5構造函數的實例化相似的都是經過new關鍵字實例化出來的。惟一的區別是ES5構造函數也能普通函數調用的形式調用。可是ES6類必須經過new調用實例化對象出來,否則會報錯的。
class Point { // ... } // 報錯 var point = Point(2, 3); // 正確 var point = new Point(2, 3);
類裏面顯示定義的全部屬性和箭頭方法都會存放到this對象裏面,可是類裏面除了箭頭方法以外的全部方法都存放到類prototype原型裏面。
//定義類 class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } say = ()=>{ } } var point = new Point(2, 3); point.toString() // (2, 3) point.hasOwnProperty('x') // true point.hasOwnProperty('y') // true point.hasOwnProperty('toString') // false point.__proto__.hasOwnProperty('toString') // true point.hasOwnProperty('say') //true
上面代碼中,x和y都是實例對象point自身的屬性(由於定義在this變量上),因此hasOwnProperty方法返回true,而toString是原型對象的屬性(由於定義在Point類上),因此hasOwnProperty方法返回false。這些都與 ES5 的行爲保持一致。
與 ES5 同樣,在「類」的內部可使用get和set關鍵字,對某個屬性設置存值函數和取值函數,攔截該屬性的存取行爲。
class MyClass { constructor() { // ... } get prop() { return 'getter'; } set prop(value) { console.log('setter: '+value); } } let inst = new MyClass(); inst.prop = 123; // setter: 123 inst.prop // 'getter'