ホームページ > 記事 > ウェブフロントエンド > JavaScript ES6でのCLASSの使い方の詳しい説明
前書き
JavaScript の場合、クラスはオプションの (必須ではない) デザイン パターンであり、JavaScript のような [[プロトタイプ]] 言語でクラスを実装するのは非常に面倒です。
文法は非常に重要な理由ですが、この不自由な感情は文法だけから来ているわけではありません。 js には文法上の欠点が数多くあります。煩雑で煩雑な .prototype 参照、プロトタイプ チェーンの上位レベルで同じ名前の関数を呼び出そうとするときの明示的な擬似多態性、そして .constructor は信頼性が低く見苦しく、コンストラクタと誤解されやすいです。 "コンストラクタ"。
さらに、実際にはクラス設計にはさらに問題があります。従来のクラス指向言語では、実際には親クラスとサブクラス、サブクラスとインスタンスの間でコピー操作が行われますが、[[Prototype]] にはコピー操作がありません。
オブジェクトの関連付けコードと動作の委任は、[[Prototype]] を非表示にする代わりに使用します。その単純さと比較すると、クラスが JavaScript に適していないことがわかります。
ES6 での CLASS の使用
JavaScript の従来の使用方法では、オブジェクト インスタンスを生成するときに、コンストラクターを定義し、 new を通じてそれを完成させる必要があります。
function StdInfo(){ this.name = "job"; this.age = 30; } StdInfo.prototype.getNames = function (){ console.log("name:"+this.name); } //得到一个学员信息对象 var p = new StdInfo()
JavaScript にはオブジェクトのみが存在し、クラスは存在しません。これはプロトタイプベースの言語であり、プロトタイプ オブジェクトは新しいオブジェクトのテンプレートであり、独自のプロパティを新しいオブジェクトと共有します。この記述方法は従来のオブジェクト指向言語とは大きく異なるため、初心者は簡単に混乱する可能性があります。
クラスを定義する
ES6 では、クラスがオブジェクトのテンプレートとして追加されました。 class を通じてクラスを定義します。
//定义类 class StdInfo { constructor(){ this.name = "job"; this.age = 30; } //定义在类中的方法不需要添加function getNames(){ console.log("name:"+this.name); } } //使用new的方式得到一个实例对象 var p = new StdInfo();
上記の記述はより明確で、オブジェクト指向プログラミングの構文に似ており、理解しやすいようです。
定義されたクラスは単なる構文糖であり、より簡潔で明確な構文でオブジェクトを作成し、関連する継承を処理できるようになります。
//定义类 class StdInfo { //... } console.log(typeof StdInfo); //function console.log(StdInfo === StdInfo.prototype.constructor); //true
上記のテストからわかるように、クラスの型は関数、つまりコンストラクターを指す「特殊関数」です。
関数を定義するには、関数宣言と関数式の 2 つの方法があります。クラスを定義する方法も、クラス宣言とクラス式です。
クラス宣言
クラス宣言は、キーワード class、その後にクラス名、そして中括弧のペアを使用してクラスを定義する方法です。定義する必要があるメソッドを中括弧で囲みます。
//定义类,可以省略constructor class StdInfo { getNames(){ console.log("name:"+this.name); } } // ------------------------------------- //定义类,加上constructor class StdInfo { //使用new定义实例对象时,自动调用这个函数,传入参数 constructor(name,age){ this.name = name; this.age = age; } getNames(){ console.log("name:"+this.name); } } //定义实例对象时,传入参数 var p = new StdInfo("job",30)
constructor は、new を使用してインスタンス オブジェクトを定義すると、コンストラクター関数が自動的に実行され、必要なパラメーターが渡され、コンストラクターの実行後にインスタンス オブジェクトが自動的に返されます。
クラス内に存在できるコンストラクター関数は 1 つだけです。複数のコンストラクター関数を定義すると、エラーが報告されます。
コンストラクター内のこれは、新しく作成されたインスタンス オブジェクトを指します。これを使用して、新しく作成されたインスタンス オブジェクトにプロパティを拡張します。
インスタンス オブジェクトを定義する場合、初期化フェーズでは何もする必要はなく、コンストラクター関数を表示せずに記述することができます。明示的に定義されていない場合は、空のコンストラクター メソッドがデフォルトで追加されます。constructor(){}
クラス式
クラス式は、関数式と同様に、クラスを定義する別の形式であり、関数を次のように受け取ります。値が割り当てられます。変数に。定義したクラスを変数に割り当てることができます。この場合、変数はクラス名になります。 class キーワードの後のクラス名はオプションです。存在する場合は、クラス内でのみ使用できます。
クラス名を後ろに付けてクラスを定義します:
const People = class StdInfo { constructor(){ console.log(StdInfo); //可以打印出值,是一个函数 } } new People(); new StdInfo(); //报错,StdInfo is not defined;
定義クラスの後にクラス名はありません:
const People = class { constructor(){ } } new People();
すぐに実行されるクラス:
const p = new class { constructor(name,age){ console.log(name,age); } }("job",30)
クラス、でクラスの前に新規を追加します。 p はクラスのインスタンス オブジェクトです。
変数の昇格はありません
クラスを定義する場合、関数の宣言とは異なり、最初にクラスを定義してから使用することしかできません。
//-----函数声明------- //定义前可以先使用,因为函数声明提升的缘故,调用合法。 func(); function func(){} //-----定义类--------------- new StdInfo(); //报错,StdInfo is not defined class StdInfo{}
継承の拡張
クラス間の継承を実装するには、extends キーワードを使用します。これは、ES5 で継承を使用するよりもはるかに便利です。
//定义类父类 class Parent { constructor(name,age){ this.name = name; this.age = age; } speakSometing(){ console.log("I can speek chinese"); } } //定义子类,继承父类 class Child extends Parent { coding(){ console.log("coding javascript"); } } var c = new Child(); //可以调用父类的方法 c.speakSometing(); // I can speek chinese
継承を使用して、サブクラスは親クラスのメソッドを持ちます。
サブクラスにコンストラクターがある場合は、super を使用する必要があります。
//定义类父类 class Parent { constructor(name,age){ this.name = name; this.age = age; } speakSometing(){ console.log("I can speek chinese"); } } //定义子类,继承父类 class Child extends Parent { constructor(name,age){ //不调super(),则会报错 this is not defined //必须调用super super(name,age); } coding(){ console.log("coding javascript"); } } var c = new Child("job",30); //可以调用父类的方法 c.speakSometing(); // I can speek chinese
サブクラスはコンストラクター メソッドでスーパー メソッドを呼び出す必要があります。そうしないと、新しいインスタンスの作成時にエラー (これは定義されていません) が報告されます。これは、サブクラスが独自の this オブジェクトを持たず、親クラスの this オブジェクトを継承して処理するためです。スーパー メソッドが呼び出されない場合、サブクラスはこのオブジェクトを取得しません。