『ES 6学習4』クラス


JS言語の伝統的な方法は構造関数によって定義され、新しいオブジェクトを生成します.ES 6はクラスという概念を対象としたテンプレートを導入しています.クラスのキーワードによってクラスを定義できます.
基本文法
function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ',' + this.y + ')';
}
Point.protortype.doStuff = function () {
  console.log('stuff');
}
//    
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ',' + this.y + ')';
  }

  doStuff() {
    console.log('stuff');
  }
}

typeof Point // "function"
Point === Point.prototype.constructor // true
上のコードは、クラスのデータタイプが関数であり、クラス自体が構造関数を指すことを示しています.クラスのすべての方法はクラスのプロトタイプの属性に定義されます.クラスの例で方法を呼び出すと、プロトタイプを呼び出す方法です.constructorメソッドは、newコマンドによりオブジェクトのインスタンスを生成する際に自動的に呼び出すデフォルトの方法です.もし定義が示されていないならば、空いているconstrutor方法はデフォルトで追加されます.
クラスのインスタンスオブジェクト
インスタンスオブジェクトを生成する場合は、ES 5と同様に、newコマンドを使用します.ES 5とは異なり、newを忘れるとエラーが発生します.
class Point {
}
//    
class Point {
  constructor() {
  }
}
var b = new Point(2, 3); //   Point  
var c = Pint(2, 3) //   
クラス表現
関数と同様に、クラスは式の形式で定義できます.
const MyClass = class Me { 
  getClassName() {
    return Me.Name;
  }
}
注意したいのはこのクラスの名前はMyClassで、Meではなく、MeはClassの内部だけで定義されています.Class内部で使われていない場合は、Meを省略することができます.
let int = new MyClass();
int.getClassName() // Me
Me.Name //   

const MyClass = class { 
  getClassName() {
    return Me.Name;
  }
}
#        
        , ES5    。
new Foo()//エラーclass Foo{}
# Class     
Class                 。
class MyClass{myProp=42;
constructor(){
console.log(this.myProp); // 42
}
new.target属性
ES 6はnew.target属性を導入し、newコマンドが作用する構造関数を返します.構造関数がnewコマンドで呼び出されない場合、new.targetはundefinedに戻ります.この属性を利用して、構造関数の呼び出しを決定できます.
function Person(name) {
  if (new.target !== undefined) {
    this.name = name;
  } else {
    throw new Error('    new    ')
  }
  /*      
 if (new.target == Person) {
    this.name = name;
  } else {
    throw new Error('    new    ')
  }*/   
}

var Person = new Person('  '); //   
var notAPerson = Person.call(person, '  '); //  
Class内部でnew.targetを呼び出し、現在のクラスに戻ります.
class Rectangle {
  constructor(length, width) {
    console.log(new.target === Rectangle);
    this.length = length;
    this.width = width;
  }
}

var obj = new Rectangle(3, 4); //   true
注意すべきなのは、基礎父類の場合はnew.targetが戻ってくるなどです.この特徴を利用して、独立して使うのではなく、継承してから使えるクラスを書くことができます.
class Shape {
  constructor() {
    if (new.target === Shape) {
      throw new Error('       ');
    }
  }  
}

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

var x = new Shape(); //   
var y = new Rectangle(); //   
クラスの継承
Classはextensキーワードによって継承を実現することができます.このようなconstructor方法でsuper方法を呼び出さなければなりません.これは、子類は自分のthisの対象ではなく、父類のthisの対象を継承しているからです.サブクラスによって定義されたconstructorメソッドがないと、constructorメソッド(superを呼び出す)がデフォルトで追加されます.
class Point { /* ... */}

class ColorPoint extends Point {
  constructor() {
    //     super();
  }
}

let cp = new ColorPoint(); //   
もう一つの注意点は、サブクラスのコンストラクタではsuperを呼び出した後にのみthisキーが使用できます.そうでないとエラーが発生します.
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }  
}

class ColorPoint extends Point {
  constructor(x, y , color) {
    this.color = color; //  
    super(x, y);
    this.color = color; //  
  }
}
superキーワード
関数として使用
スーパーは関数としてもいいし、オブジェクトとしても使えます.第一の場合、superは関数として呼び出された時、親の構造関数を表します.しかし、Super内部のthisがインスタンスを指す、などの例を返します.したがって、スーパーはA.prototype.com nstructor.callに相当します.
class A {
  constructor() {
    console.log(new.target.name);
  }
}

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

new A // A
new B // B
オブジェクトとして
第二の場合、superを対象とする場合は、普通の方法で親類の原型オブジェクトを指す.静的方法では親を指します.
class A {
  p() {
    return 2;
  }  
}

class B extends A {
  constructor() {
    super();
    console.log(super.p()); // 2      A.prototype.p()
  }
}

let b = new B(); 
this指向
ES 6は、superによって親タイプのメソッドを呼び出すと、superがサブクラスのthisをバインドすると規定しています.superを通してある属性に値を割り当てると、superはthisであり、その属性はサブクラスのインスタンスの属性となる.
class A {
  constructor() {
    this.x = 1;
  }
  print() {
    console.log(this.x);
  }
}

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

let b = new B();
b.m() // 3
ps…参考資料『ES 6標準入門』(第三版)