ES6 裏面類的簡單理解

類的簡介

1.1 類的由來

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

poin構造函數.jpg

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)

運行結果:函數

point類.jpg

經過上面的代碼能夠看出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

1.2 constructor

constructor方法是類的默認方法,經過new命令生成對象實例時,自動調用該方法。一個類必須有constructor方法,若是沒有顯式定義,一個空的constructor方法會被默認添加。

class Point {
}

// 等同於
class Point {
  constructor() {}
}

類經過new關鍵字實例化的時候默認自動調用constructor構造方法,constructor構造方法返回一個類實例(即this對象)

1.3 類的實例

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 的行爲保持一致。

1.4 取值函數(getter)和存值函數(setter)

與 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'
相關文章
相關標籤/搜索