今回は、JSクラス、コンストラクター、ファクトリー関数の使い方についてお届けします。JSクラス、コンストラクター、ファクトリー関数を使用する際の注意点について、実際の事例を見てみましょう。
ES6 時代では、オブジェクトを作成する方法が増えました、さまざまなシナリオでさまざまな方法を選択できます。現在、オブジェクトを構築するには、クラス キーワード、コンストラクター、ファクトリ関数という 3 つの主な方法があります。これらはすべてオブジェクトを作成するための手段ですが、日々の開発ではこれらの違いに基づいて選択する必要もあります。
まず、これら 3 つのメソッドがどのようなものかを見てみましょう
// class 关键字,ES6新特性 class ClassCar { drive () { console.log('Vroom!'); } } const car1 = new ClassCar(); console.log(car1.drive()); // 构造函数 function ConstructorCar () {} ConstructorCar.prototype.drive = function () { console.log('Vroom!'); }; const car2 = new ConstructorCar(); console.log(car2.drive()); // 工厂函数 const proto = { drive () { console.log('Vroom!'); } }; function factoryCar () { return Object.create(proto); } const car3 = factoryCar(); console.log(car3.drive());
これらのメソッドはプロトタイプの作成に基づいており、すべてコンストラクター関数でのプライベート変数の実装をサポートしています。言い換えれば、これらの関数はほとんど同じ特性を持ち、多くのシナリオで同等ですらあります。
Javascript では、すべての関数が新しいオブジェクトを返すことができます。コンストラクターやクラスではない場合は、ファクトリ関数と呼ばれます。
ES6 クラスは実際にはコンストラクターの糖衣構文です (少なくともこの段階ではこれが実装されています)。そのため、次に説明する内容はすべてコンストラクターと ES6 クラスに当てはまります:
class Foo {} console.log(typeof Foo); // function
コンストラクターと ES6 クラスの利点
ほとんどの本では、クラスとコンストラクターの使い方を教えています
コンストラクターとES6クラスの欠点
1. 新しいキーワードが必要です
ES6 では、コンストラクターとクラスの両方に新しいキーワードが必要になります。
りーES6 では、new キーワードなしでクラス関数を呼び出そうとするとタスクがスローされます。 new キーワードのないものが必要な場合は、ファクトリ関数を使用してラップするしかありません。
2. インスタンス化プロセス中の詳細は外部 API に公開されます
すべての呼び出しはコンストラクターの実装と密接に関係しています。構築プロセス中に何かを行う必要がある場合、それは非常に面倒なことになります。
3. コンストラクターはオープン/クローズドルールに従いません
新しいキーワードの詳細な処理のため、コンストラクターはオープン/クローズのルールに違反します。つまり、API は拡張のためにオープンであり、変更を避ける必要があります。
以前、クラスとファクトリ関数は非常に似ているので、クラス関数をファクトリ関数にアップグレードしても何の影響もないのではないかと疑問に思いましたが、JavaScript では影響があります。
コンストラクターまたはクラスの作成を開始したが、続けていくうちにファクトリ関数の柔軟性が必要になった場合、現時点では関数を変更してそのまま終了することはできません。
残念ながら、あなたは JavaScript プログラマーであり、コンストラクターをファクトリー関数に変換するのは大掛かりな操作です:
function Foo() { if (!(this instanceof Foo)) { return new Foo(); } }
上記の例では、クラスから開始し、最終的に特定のプロトタイプに基づいてオブジェクトを作成できるファクトリ関数に変更しました。このような関数は、インターフェイスの抽象化や特別なニーズのカスタマイズに広く使用できます。
4. コンストラクターを使用して、instanceof に機会を与えます
コンストラクターとファクトリー関数の違いは、instanceof operator です。多くの人は、コードの正確性を確保するために、instanceof を使用します。しかし、正直に言うと、これは非常に問題があるため、instanceof の使用を避けることをお勧めします。
インスタンスオブは嘘をつきます。
りーinstanceof は、他の強く型付けされた言語のようなチェックは行わず、プロトタイプ チェーン上のオブジェクトをチェックするだけです。
Constructor.prototype を変更する場合など、一部の実行コンテキストでは失敗します。
もう 1 つの例は、コンストラクターまたはクラスから始めて、それを別のオブジェクトに展開することです。これは、ファクトリ関数として書き換えられた上記の状況とまったく同じです。現時点では、instanceof にも問題が発生します。
全体として、instanceof は、コンストラクターとファクトリ関数の呼び出しにおけるもう 1 つの大きな変更です。
クラスを利用するメリット
便利な自己完結型キーワード
クラスを使用するデメリット
コンストラクターに関するすべての悪い点に加えて:
extends キーワードを使用して問題のあるクラスを作成することは、ユーザーにとって大きな誘惑になります。
クラスの階層継承は、脆弱な基底クラス (継承により基底クラスが破壊される)、ゴリラバナナなど、多くの有名な問題を引き起こします。
問題(複雑なコンテキストが混在するオブジェクト)、必然的な重複(継承が多様化するとクラスを随時変更する必要がある)など。
他の 2 つの方法でもこれらの問題が発生する可能性がありますが、extend キーワードを使用すると、環境によってこの問題が発生します。言い換えれば、再利用可能なコードではなく、柔軟性のない関係を持つコードを作成することになります。
ファクトリー関数を使用する利点
ファクトリ関数はクラスやコンストラクターよりも柔軟であり、人々を間違った道に導くことはありません。また、深い継承の連鎖に陥ることもありません。継承をシミュレートするにはさまざまな手段を使用できます
1. 任意のプロトタイプを持つ任意のオブジェクトを返します
たとえば、同じ実装の異なるインスタンスを作成したり、メディア プレーヤーで異なる API を使用して異なるメディア形式のインスタンスを作成したり、DOM 時間または ws イベント用のイベント ライブラリを作成したりできます。
ファクトリ関数は、実行コンテキストを通じてオブジェクトをインスタンス化することもでき、オブジェクト プールとより柔軟な継承モデルの恩恵を受けることができます。
2. 複雑なリファクタリングの心配はありません
ファクトリ関数をコンストラクターに変換する必要がないため、リファクタリングは必要ありません。
3. 新しいものはありません
新しいオブジェクトを作成するために new キーワードを使用する必要はありません。このプロセスは自分で習得できます。
4. この動作を標準化します
これはあなたがよく知っている this であり、これを使用して親オブジェクトを取得できます。たとえば、player.create() では、this は player を指しますが、他の this は呼び出しと適用を通じてバインドすることもできます。
5.instanceof
なら問題ない 6. 新しいものを使わずに直接書くことの読みやすさと直観性を好む人もいます。
ファクトリー機能のデメリット
プロトタイプの自動処理はなく、ファクトリ関数プロトタイプはプロトタイプ チェーンに影響を与えません。
結論
私の意見では、クラスは便利なキーワードかもしれませんが、疑いを持たないユーザーを継承の穴に導く可能性があることは隠せません。もう 1 つのリスクは、将来ファクトリ関数を使用することになり、非常に大きな変更を加えなければならない可能性です。
比較的大規模なチームで作業している場合、パブリック API を変更すると、アクセス権のないコードに干渉する可能性があるため、変更された関数の影響を無視することはできません。
Factory Pattern の優れた点は、より強力で柔軟であるだけでなく、チーム全体が API をよりシンプル、安全、軽量にすることを奨励できることです。
この記事の事例を読んだ後は、この方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。
推奨読書:
nodejsを使用してWeChatで配送先アドレスに電話をかける
以上がJSクラス、コンストラクター、ファクトリ関数の使用方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。