まず第一に、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) と同等です。 「 。」super
this
this
super
super
super
this
super()
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()
内部はthis
B を指します。
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)
。
サブクラスのバインディングによりthis
、super
特定のプロパティに値を割り当てると、割り当てられた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 におけるオブジェクトの概念とオブジェクト指向の考え方を理解していれば、クラスを理解するのは難しくありません。