Js_ ES6クラスのコンストラクターメソッドとスーパーの役割を理解する

まず第一に、ES6 はclass一種の「糖衣構文」であるため、よりエレガントに、よりオブジェクト指向プログラミングに似て書かれているだけであり、その考え方は ES5 と一貫しています。

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function() {
  return '(' + this.x + ',' + this.y + ')';
}

に相当

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

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

このconstructorメソッドはクラスのコンストラクターであり、newコマンドを通じてオブジェクト インスタンスが作成されるときに自動的に呼び出されるデフォルトのメソッドです。constructorクラスにはメソッドが必要です。明示的に定義されていない場合は、デフォルトのconsructorメソッドがデフォルトで追加されます。したがって、コンストラクターを追加しなくても、デフォルトのコンストラクターが存在します。一般的なconstructorメソッドはインスタンス オブジェクトを返しますが、返されるインスタンス オブジェクトがこのクラスのインスタンスではないように、新しいオブジェクトを返すようにthisメソッドを指定することもできます。constructor

superキーワードの役割を詳しく見てみましょう。

superこのキーワードは、関数またはオブジェクトとして使用できます。どちらの場合も、その使用はまったく役に立ちません。

1. 関数として使用する

class A {}
class B extends A {
  constructor() {
    super();  // ES6 要求,子类的构造函数必须执行一次 super 函数,否则会报错。
  }
}

注:サブクラスは独自のオブジェクトを持たず、親クラスのオブジェクトを継承して処理し、親クラスのコンストラクターを表すため、このメソッドconstructorは で呼び出す必要があります。これは親クラス A のコンストラクターを表しますが、サブクラス B のインスタンスを返します。つまり、internal はBを参照するため、ここでは ```A.prototype.constructor.call(this, props) と同等です。 「 。」superthisthissupersupersuperthissuper()

class A {
  constructor() {
    console.log(new.target.name); // new.target 指向当前正在执行的函数
  }
}

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

new A(); // A
new B(); // B

super()実行すると、親クラス A のコンストラクターではなく、サブクラス B のコンストラクターを指すことがわかります。つまり、super()内部はthisB を指します。

2. オブジェとして使う

通常のメソッドでは、親クラスのプロトタイプ オブジェクトを指しますが、静的メソッドでは、親クラスを指します。

class A {
  c() {
    return 2;
  }
}

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

let b = new B();

上記のコードでは、サブクラス B でオブジェクトとして使用されてsuper.c()います。superこのとき、super通常の方法では を指すのでA.prototype、 とsuper.c()同等になりますA.prototype.c()

super親クラスのメソッドを呼び出すと、superサブクラスがバインドされますthis

class A {
  constructor() {
    this.x = 1;
  }
  s() {
    console.log(this.x);
  }
}

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

let b = new B();
b.m(); // 2

上記のコードでは、super.s()と呼ばれていますがA.prototytpe.s()A.prototytpe.s()サブクラス B をバインドするthisため、出力は 1 ではなく 2 になります。つまり、実際に実行されるのは ですsuper.s.call(this)

サブクラスのバインディングによりthissuper特定のプロパティに値を割り当てると、割り当てられたsuperプロパティthisがサブクラス インスタンスのプロパティになります。

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();

上記のコードで、super.x値 3 を割り当てることは、this.x値 3 を に割り当てることと同じです。そして、 を読み込むとsuper.x、 が呼び出されますA.prototype.xが、メソッドがないxため、 unknown が返されます。

superを使用する場合は、関数として使用するかオブジェクトとして使用するかを明示的に指定する必要があることに注意してください。指定しないとエラーが報告されます

class A {}
class B extends A {
  constructor() {
    super();
    console.log(super); // 报错
  }
}

console.log(super);上記のコードではsuper関数として使用されているのかオブジェクトとして使用されているのかを区別できないため、JavaScript エンジンはコードを解析するときにエラーを報告します。つまり、データ型を明確に指定できる場合super、エラーは報告されません。

最後に、オブジェクトは常に他のオブジェクトから継承するため、どのオブジェクトでもキーワードを使用できますsuper

結論:
ES6 クラスは結局のところ「文法糖」なので、JavaScript におけるオブジェクトの概念とオブジェクト指向の考え方を理解していれば、クラスを理解するのは難しくありません。

おすすめ

転載: blog.csdn.net/qq_41916378/article/details/109714768