ES 6のクラス

4695 ワード

注:この文章は私がチェン一峰先生の[ECMAScript 6入門]の文章を参考にして、自分で記録したノートで、詳しい内容はチェン一峰先生の文章を移動してください.
1. CLASS
ES 6の「クラス」の上に引き続き存在します.実際、クラスのすべてのメソッドはクラスのprototypeプロパティに定義されます.
class Point {
  constructor() {
    // ...
  }

  toString() {
    // ...
  }

  toValue() {
    // ...
  }
}

//  

Point.prototype = {
  constructor() {},
  toString() {},
  toValue() {},
};

クラスのメソッドはprototypeオブジェクト上に定義されているため、クラスの新しいメソッドをprototypeオブジェクト上に追加するObject.assignメソッドは、クラスに複数のメソッドを一度に追加するのに便利である.
class Point {
  constructor(){
    // ...
  }
}

Object.assign(Point.prototype, {
  toString(){},
  toValue(){}
});

prototypeオブジェクトのconstructorプロパティは、ES 5の動作と一致する「クラス」そのものを直接指します.Point.prototype.constructor === Point //
  • contructor

  • constructorメソッドはクラスのデフォルトメソッドであり、newコマンドでオブジェクトインスタンスを生成すると自動的に呼び出されます.クラスにはconstructorメソッドが必要です.明示的に定義されていない場合は、空のconstructorメソッドがデフォルトで追加されます.
  • クラスのインスタンス
  • インスタンスのプロパティは、明示的に定義されていない限り(thisオブジェクトに定義されている)、プロトタイプに定義されています(classに定義されています).
    class people {
            constructor(x,y){
                this.x =x ;
                this.y =y
            }
            sayNum(){
                console.log(this.x)
            }
        }
        
        let wt =new people(1,2);
        wt.sayNum()
        console.log(wt.hasOwnProperty('x'))  //true
        
        function hasPrototypeProperty(obj,pro){
            return !obj.hasOwnProperty(pro)
        }
        console.log(hasPrototypeProperty(wt,'sayNum')) //true
    

    Classの値取り関数(getter)と値取り関数(setter)はES 5と同様に、「クラス」の内部で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'
    
  • CLASS継承
  • class people {
            constructor(x,y){
                this.x =x ;
                this.y =y
            }
            sayNum(){
                console.log(this.x)
            }
        }
        
        class student extends people {
            constructor(x,y){
                super(x,y) // 
            }
            saydNum(){
                super.sayNum()
            }
        }
        let mj=new student(101,102)
        mj.saydNum()
    
    superここでは、親の構造関数を表し、親のthisオブジェクトを新規作成します.
    サブクラスはconstructorメソッドでsuperメソッドを呼び出す必要があります.そうしないと、インスタンスを新規作成するときにエラーが発生します.これは,子クラスが自分のthisオブジェクトを持たず,親クラスのthisオブジェクトを継承して加工するためである.superメソッドを呼び出さないと、サブクラスはthisオブジェクトを取得できません.
    もう1つ注意しなければならないのは、サブクラスのコンストラクション関数でsuperを呼び出した後にのみthisキーワードを使用できます.そうしないと、エラーが発生します.これは、サブクラスインスタンスの構築が、親インスタンスの加工に基づいており、superメソッドのみが親インスタンスを返すためです.
  • Object.getPrototypeOf()
  • Object.getPrototypeOfメソッドは、子から親を取得するために使用することができる.
    Object.getPrototypeOf(ColorPoint) === Point
    // true
    

    したがって,この手法を用いて,あるクラスが別のクラスを継承しているか否かを判断することができる.
  • super
  • superというキーワードは、関数としてもオブジェクトとしても使用できます.この2つの場合、その使い方は全く違います.1つ目の場合、superが関数として呼び出されると、親の構造関数を表します.ES 6は、サブクラスのコンストラクション関数がsuper関数を1回実行しなければならないことを要求する.
    class A {}
    
    class B extends A {
      constructor() {
        super();
      }
    }
    

    上のコードでは、サブクラスBのコンストラクション関数のうちsuper()は、親クラスを呼び出すコンストラクション関数を表します.これは必須です.そうしないとJavaScriptエンジンがエラーを報告します.
    なお、superは親クラスAのコンストラクション関数を表すが、サブクラスBの例、すなわちsuper内部のthisはBを指すため、super()はここではA.prototype.constructor.call(this)。に相当する
    第2の場合、superがオブジェクトである場合、一般的な方法では、親のプロトタイプオブジェクトを指す.静的メソッドでは、親を指します.
    class A {
      p() {
        return 2;
      }
    }
    
    class B extends A {
      constructor() {
        super();
        console.log(super.p()); // 2
      }
    }
    
    let b = new B();
    

    ここで、superは親のプロトタイプオブジェクトを指すため、親インスタンスに定義されたメソッドまたは属性は、superによって呼び出されません.
    class A {
      constructor() {
        this.p = 2;
      }
    }
    
    class B extends A {
      get m() {
        return super.p;
      }
    }
    
    let b = new B();
    b.m // undefined
    

    上のコードでは、pは親Aのインスタンスの属性、superである.pはそれを参照できません.
    属性が親クラスのプロトタイプオブジェクトに定義されている場合、superは取得できます.
    class A {}
    A.prototype.x = 2;
    
    class B extends A {
      constructor() {
        super();
        console.log(super.x) // 2
      }
    }
    
    let b = new B();
    

    superがオブジェクトとして静的メソッドで使用される場合、superは親のプロトタイプオブジェクトではなく親を指します.
    class Parent {
      static myMethod(msg) {
        console.log('static', msg);
      }
    
      myMethod(msg) {
        console.log('instance', msg);
      }
    }
    
    class Child extends Parent {
      static myMethod(msg) {
        super.myMethod(msg);
      }
    
      myMethod(msg) {
        super.myMethod(msg);
      }
    }
    
    Child.myMethod(1); // static 1
    
    var child = new Child();
    child.myMethod(2); // instance 2