
JavaScriptには、継承、クラスとプロトタイプ、ファクトリーと不純物、直接と間接、およびいくつかのメソッドのハイブリッドの多くの異なるメソッドがあります。 ただし、Node.jsには
util.inherits (ChildClass、ParentClass)を使用するネイティブな方法があります。 最近まで、私は組み込みメソッドにのみNodeメソッドを使用し(EventEmitter、Readable / Writable Stream、Domain、Bufferなどの独自の子孫を作成する必要があったとき)、すべてのJavaScriptに共通のプラクティスを使用してサブジェクトエリアをモデル化しました。 そして今、初めて、組み込みの継承クラスではなく、ドメインクラスではなく、
Impressアプリケーションサーバーのシステムコードで大きな影響を受けるクラスのシステムクラスの独自の階層を実装する必要がありました。 どういうわけか、util.inheritsの使用だけでは不十分でした。記事を検索し、必要なものを完全に見つけられませんでした。彼女もあなたを助けてくれることを願っています。 煩雑さのために、子クラスでオーバーライドされたメソッドから親クラスのメソッドを呼び出す実装が好きではない
ことをすぐに
警告します。したがって、代替メソッドを歓迎し、リポジトリまたはこのノートへのコメントで招待します。
実装要件:- Node.jsネイティブ継承util.inheritsの使用
- 祖先クラスとクラスの子孫へのフィールドとメソッドの定義
- 子コンストラクターから親コンストラクターを呼び出す機能
- 子クラスのメソッドをオーバーライドする機能
- 子クラスでオーバーライドされたメソッドから親クラスのメソッドを呼び出す機能
基本的な例継承によって接続された2つのクラスがあり、子のコンストラクターからClassName.super_.apply(this、arguments)を介して親クラスのコンストラクターを呼び出します。 当然、この呼び出しは、子の最初、コンストラクター、およびその終わりまたは中間の両方で行うことができます。 呼び出しは条件にラップできます。 祖先のコンストラクターの機能へのロールバックを完全に制御します。
var util = require('util');
拡張例ここでは、プロトタイプを介して、親クラスと子の両方のメソッドとプロパティをすでに定義しています。 これらは、生成されたインスタンスのメソッドとプロパティではなく、クラス自体のメソッドとプロパティになることを思い出させてください。 それらは標本に表示されますが、プロトタイプに含まれています。 コンソールの結論は、すべてが正常に機能し、便利で予測可能なものであることを示しています。
var util = require('util');
メソッドのオーバーライドの例さらに興味深いことに、ParentClassにはmethodNameメソッドがあり、新しいオーバーライドされた実装から祖先メソッドを呼び出す機能を使用して、ChildClassの子孫で再定義する必要があります。
var util = require('util');
親クラスのメソッドを呼び出すためのこの構築:ClassName.super_.prototype.methodName.apply(これ、引数)は確かに非常に面倒ですが、ネイティブノードの継承の実装に別の方法は見つかりませんでした。 私に起こった唯一の疑わしい改善は、次の例で与えられます。
継承の代替方法先祖メソッドを呼び出す構文を簡素化するために、オーバーライドメソッドをFunction基本クラスに追加して価格を支払う必要があります。 一般的なすべての関数(ノードの現在のコンテキスト、またはサンドボックス/サンドボックス内、これがすべてシールドメモリコンテキストで実行されるコード-サンドボックス内で発生する場合) その後の呼び出しはエレガントになります:this.inherited(...)またはユニバーサルオプションthis.inherited.apply(this、arguments)を使用できます。このオプションでは、すべてのパラメーターを名前で親メソッドの呼び出しに置き換える必要はありません。
var util = require('util');
UPD:メソッドのオーバーライドを伴う最適なオプションxdenserとともに、
super_を使用せず、適用する必要のない、最も高速でかなり簡潔なバージョンが見つかりました。
var util = require('util');
性能比較望ましいオプションは明らかですが、測定を行う必要があります。 同じ機器で先祖クラスメソッドを呼び出す10,000,000回の呼び出し:
- ClassName.super_.prototype.methodName.apply(this、arguments); 424ミリ秒
- Function.prototype.override(fn)およびthis.inherited(par); 1972ミリ秒。
- Function.prototype.override(fn)およびthis.inherited.apply(this、arguments); 1800ミリ秒
- 最後のオプションは、オーバーライド(子、fn)およびmethodName.inherited.call(this、par)です。 338ミリ秒
ロシア語と英語のコード例とコメントを含むリポジトリ:
https :
//github.com/tshemsedinov/node-inheritance