Es6 類class的關鍵 super、static、constructor、new.target

ES6引入了Class(類)這個概念,做爲對象的模板,經過class關鍵字,能夠定義類。基本上,ES6的class能夠看做只是一個語法糖,它的絕大部分功能,ES5均可以作到,新的class寫法只是讓對象原型的寫法更加清晰、更像面向對象編程的語法而已。編程

那麼如何掌握類這項技能,讓我來陪你們一塊兒學習:app

 1.super關鍵字函數

 super用在調用的時候有兩種狀況:

第一種狀況,super做爲函數調用時,表明父類的構造函數。
第二種狀況,super做爲對象時,在普通方法中,指向父類的原型對象;在靜態方法中,指向父類。工具

 

class Person {
  constructor (name) {
    this.name = name;
  }
  height(){
      console.log(1);
  }
  static weight(){
      console.log(2);
  }
}
class Student extends Person {
  constructor (name, age) {
    super();  //表明父類的構造函數
    this.age = age;
  }
  height(){
      super.height(); //指向父類的原型對象
  }
  static weight(){
      super.weight(); //指向父類
  }
}

若是子類調用constructor,那麼子類必須在constructor方法中調用super方法,不然新建實例時會報錯。這是由於子類沒有本身的this對象,而是繼承父類的this對象,而後對其進行加工。若是不調用super方法,子類就得不到this對象。學習

總結下:ui

super 關鍵字用於調用一個對象的父對象上的函數。
super.prop 和 super[expr] 表達式在類 和 對象字面量 任何 方法定義 中都是有效的。
在構造函數中使用時,super關鍵字單獨出現,必須在能夠使用this關鍵字以前使用。此關鍵字也可用於調用父對象上的函數。this

 

2.static關鍵字spa

類至關於實例的原型, 全部在類中定義的方法, 都會被實例繼承。 若是在一個方法前, 加上static關鍵字, 就表示該方法不會被實例繼承, 而是直接經過類來調用, 這就稱爲「 靜態方法」。prototype

靜態方法調用直接在類上進行,而在類的實例上不可被調用。code

靜態方法一般用於建立 實用/工具 函數。

經過例子咱們能夠發現,靜態方法是經過類名直接調用的

從另外一個靜態方法爲了在同一個類的另外一個靜態方法中調用一個靜態方法,你能夠使用 this 關鍵字。

class StaticMethodCall {
    static staticMethod() {
        return 'Static method has been called';
    }
    static anotherStaticMethod() {
        return this.staticMethod() + ' from another static method';
    }
}
StaticMethodCall.staticMethod();
// 'Static method has been called'

StaticMethodCall.anotherStaticMethod();
// 'Static method has been called from another static method'

從類的構造函數和其餘方法靜態方法不能直接在非靜態方法中使用 this 關鍵字來訪問。你須要使用類名來調用它們:CLASSNAME.STATIC_METHOD_NAME() 或者將其做爲構造函數的屬性來調用該方法: this.constructor.STATIC_METHOD_NAME().

class StaticMethodCall {
    constructor() {
        console.log(StaticMethodCall.staticMethod());
        // 'static method has been called.'
        console.log(this.constructor.staticMethod());
        // 'static method has been called.'
    }
    static staticMethod() {
        return 'static method has been called.';
    }
}

 

3.new.target 關鍵字

    new.target屬性容許你檢測函數或構造方法是否經過是經過new運算符被調用的。在經過new運算符被初始化的函數或構造方法中,new.target返回一個指向構造方法或函數的引用。在普通的函數調用中,new.target 的值是undefined。

  怎麼理解這段話,也就是說new.target的功能就是用來檢測函數的調用是否是經過 new 去建立一個新對象的,並且new.target返回的是一個指向函數的引用,也就是說咱們可以肯定是哪一個函數進行了new操做

class A {
  constructor() {
    console.log(new.target.name);
  }
}

class B extends A { constructor() { super(); } }

var a = new A(); // logs "A"
var b = new B(); // logs "B"

new.target 最大的做用就是讓構造器知道當前到底 new 的是哪一個類。

 

延伸下。ES6以前怎麼實現這個功能?

var A = function A() {
  if(!(this instanceof A)) throw 'Constructor A requires "new"';
  // ···
};

然而這依然能夠經過 call 或 apply 來調用。好比:

var a = A.call(Object.create(A.prototype));

那麼用ES6就是下面這樣操做了

var A = function A() {
  if(!new.target) throw 'Constructor A requires "new"';
  // ···
};

 4.constructor關鍵字

構造方法是建立和初始化使用類建立的一個對象的一種特殊方法。

class Square extends Polygon {
  constructor(length) {
    // 在這裏調用父類的"length",賦值給矩形的"width"和"height"。
    super(length, length);
    // 注意:子類必須在constructor方法中調用super方法,不然新建實例時會報錯。
    this.name = 'Square';
  }

  get area() {
    return this.height * this.width;
  }

  set area(value) {
    this.area = value;
  } 
}

若是沒有顯式定義,會默認添加一個空的constructor方法。對於基類"Base classes",默認構造方法以下:

constructor() {}

對於派生類"Derived classes" ,默認構造方法以下:

constructor(...args) {
  super(...args);
}
相關文章
相關標籤/搜索