ES6 類(class)


  JS語言的傳統方法是通過構造函數,定義並生成新對象,是一種基於原型的面向對象系統。在ES6中新增加了類的概念,可以使用 class 關鍵字聲明一個類,之后以這個類來實例化對象。
  構造函數示例
const Demo = function (a, b) {
    this.a = a;
    this.b = b;
    return this;
};

Demo.prototype = {
    constructor: Demo,
    print: function () {
        console.log(this.a + ' ' + this.b);
    }
};


const demo = new Demo('hello', 'world').print();
  class示例
class Demo {
    constructor(a, b) {
        this.a = a;
        this.b = b;
        return this;
    }

    print() {
        console.log(this.a + ' ' + this.b);
    }
};
const demo = new Demo('hello', 'world').print();
console.log(typeof demo);
  1 Demo中的constructor方法是構造方法,this關鍵字則代表實例對象。也就是說,ES5的構造函數Demo,對應ES6的Demo這個類的構造方法。
  2 Demo這個類除了構造方法,還定義了一個print方法。注意,定義"類"的方法的時候,前面不需要加上function這個關鍵字,直接把函數定義放進去了就可以了。另外,方法之間不需要逗號分隔,加了會報錯。
  3 構造函數的prototype屬性,在ES6的“類”上面繼續存在。而且類的所有方法都定義在類的prototype屬性上面。

class Point {
    string(){
        return 'aaa'
    }
}
class ColorPoint extends Point {
    constructor(color) {
        super(); // 調用父類的constructor()
        this.color = color;
    }

    toString() {
        return (this.string() )
    }
}
console.log(new ColorPoint('#000'));    //console.log(new ColorPoint(1,2,'#000'))
console.log(new ColorPoint('#000').toString());     //aaa

console.log(new ColorPoint('#000').__proto__);      //Point {constructor: function, toString: function}
console.log(ColorPoint.__proto__);      // class Point{...}
console.log(ColorPoint.prototype);      // Point {constructor: function, toString: function}
console.log(ColorPoint.__proto__.prototype);      // Object {constructor: function, string: function}

作為一個對象,子類(B)的原型(__proto__屬性)是父類(A);作為一個構造函數,子類(B)的原型(prototype屬性)是父類的實例。
  Object.setPrototypeOf(B.prototype, A.prototype);
  等同於
  B.prototype.__proto__ = A.prototype;

  Object.setPrototypeOf(B, A);
  等同於
  B.__proto__ = A;

super
  1、super作為函數調用時,代表父類的構造函數。ES6 要求,子類的構造函數必須執行一次super函數。
  2、super作為對象時,在普通方法中,指向父類的原型對象;在靜態方法中,指向父類
  super代表了父類A的構造函數,但是返回的是子類B的實例,即super內部的this指的是B,因此super()在這里相當於A.prototype.constructor.call(this)。
class A {
    constructor() {
        this.x = 1;
    }
    print() {
        console.log(this.x);
    }
}

class B extends A {
    constructor() {
        super();
        this.x = 2;
    }
    m() {
        super.print();
    }
}

let b = new B();
b.m() // 2
class A {
    constructor() {
        this.x = 1;
    }
}

class B extends A {
    constructor() {
        super();
        this.x = 2;
        super.x = 3;
        console.log(super.x); // undefined
        console.log(this.x); // 3
    }
}

let b = new B();

  類相當於實例的原型,所有在類中定義的方法,都會被實例繼承。如果在一個方法前,加上static關鍵字,就表示該方法不會被實例繼承,而是直接通過類來調用,這就稱為“靜態方法”。
new.target
  new是從構造函數生成實例的命令。ES6為new命令引入了一個new.target屬性,(在構造函數中)返回new命令作用於的那個構造函數。如果構造函數不是通過new命令調用的,new.target會返回undefined,因此這個屬性可以用來確定構造函數是怎么調用的。
  Class內部調用new.target,返回當前Class。
class Rectangle {
    constructor(length, width) {
        console.log(new.target === Rectangle);
        this.length = length;
        this.width = width;
    }
}

var obj = new Rectangle(3, 4); // 輸出 true
  ps:子類繼承父類時,new.target會返回子類。
class Shape {
    constructor() {
        if (new.target === Shape) {
            throw new Error('本類不能實例化');
        }
    }
}

class Rectangle extends Shape {
    constructor(length, width) {
        super();
        console.log(length+' '+width)
        // ...
    }
}

var y = new Rectangle(3, 4);  // 正確
var x = new Shape();  // 報錯

 

靜態方法

  函數命前聲明static,就為靜態方法。該方法不會被實例繼承,而是直接通過類來調用。
class Person {
    constructor(name) {
        this.name = name;
    }
    static say () {
        console.log("say hi");
    }
};
Person.say();

 靜態屬性

  靜態屬性指的是Class本身的屬性,即Class.propname,而不是定義在實例對象(this)上的屬性。

class Foo {
}

Foo.prop = 1;
Foo.prop // 1

  新寫法 

class MyClass {
    static myStaticProp = 42;

    constructor() {
        console.log(MyClass.myStaticProp); // 42
    }
}

 

實例屬性

class ReactCounter extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0
        };
    }
}

  新寫法

class ReactCounter extends React.Component {
    state = {
        count: 0
    };
}

 

 




  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM