プロトタイプの継承はクラスの継承よりも単純で柔軟であることに誰もが同意しているようです。私が読んだ文献で見たことがないのは、プロトタイプの継承ではできるが、クラシックではできないことの非常に多くの例です。だから私は簡単な質問をします:
プロトタイプ継承では使用でき、クラス継承では使用できないパターンとは?
プロトタイプの継承はクラスの継承よりも単純で柔軟であることに誰もが同意しているようです。私が読んだ文献で見たことがないのは、プロトタイプの継承ではできるが、クラシックではできないことの非常に多くの例です。だから私は簡単な質問をします:
プロトタイプ継承では使用でき、クラス継承では使用できないパターンとは?
1 つの違い (おそらく少なくとも概念的には) は、クラスの継承が、子が親の IS-A 型であることを意味することです。プロトタイプの継承には、そのような意味はありません。哺乳動物は猫の原型ですが (Merriam-Webster の定義によれば、これは猫が「パターン」であることを意味します)、他には何もありません。猫は自由に行動を削除/追加/変更できます。
わかりました、1 つ追加します。プロトタイプ リンクが、オブジェクトのクラス全体のモンキー パッチ メソッドに対して有効であるという事実を使用します。
var Cat = function(catName) {
this.catName = catName;
};
Cat.prototype.meow = function() {
console.log(this.catName+" says meow");
}
var mittens = new Cat("Mittens");
var whiskers = new Cat("Whiskers");
mittens.meow(); // "Mittens says meow"
whiskers.meow(); // "Whiskers says meow"
// All cats are now angry
Cat.prototype.meow = function() {
console.log(this.catName+" says hissssss");
}
mittens.meow(); // "Mittens says hissssss"
whiskers.meow(); // "Whiskers says hissssss"
これは、ある種のグローバル イベントに応答して、まったく異なるが一貫した方法で突然動作を開始する必要があるオブジェクトがある場合に役立ちます。たぶん次のようなものです:
JavaScriptには実際のクラス継承がないため、他の言語のクラス継承と比較しない限り、JavaScriptの従来のクラス継承ではできないことを説明する文献はおそらく見つかりません。
だから私はあなたの質問をあなたが意味するかのように考えます:
JavaScriptプロトタイプ継承で使用できるパターンのうち、それをサポートする言語のクラス継承では使用できないパターンは何ですか?
R =一般に、クラス継承に基づくほとんどのオブジェクト指向言語は、厳密な構造を持つオブジェクトを生成します。それらは、存続期間中は常に同じメソッドとプロパティを持ち、同じクラスのすべてのオブジェクトは同じ構造を持ちます。
したがって、一般に、クラス継承言語では実装できないプロトタイプベースの言語で適用できるパターンは、以下に依存するパターンです。
*これは、動的なクロスドメインコラボレーションの性質により、JavaScriptで非常によくサポートされています。他のWebサイトから外部スクリプトをロードする必要があるが、これらの外部ライブラリからソースコードを変更できずに新しい機能を追加する必要がある場合があります。
私はあなたの前提に同意するとは思いませんが、プロトタイプベースの継承の主な利点は、クラスのインスタンスが既に存在する場合でも、クラスのすべてのメンバーでプロパティとメソッドを実行時に割り当てることができることです。
私の理論家は、実際にはこれらの意味のいくつかにうんざりしています。コードのどの部分がクラス構造を完全に再定義したかわからないデバッグを想像してみてください。それは気が遠くなるようなものではありません。
しかし、私はそれが有用であることが証明されていると言います:
かつて、ActionScript 3 コンテナー内で ActionScript 2 を使用していたとき (ほとんど非決定論的な言語であるため、気弱な人向けではありません)。この問題の未知の副作用は、メモリ レベル (私の会社のレガシー コードに不可欠なもの) の概念がなくなることです。行を追加することができました:MovieClip.prototype._level0 = _root;
そしてそれは問題を解決しました。
上記の私の主張に反論するために、事後にすべてのインスタンスを変更できるという事実は、元のコード ベース (例のように) にアクセスできない状況である程度の力を提供しますが、大きなものは見当たりません。それ以上の利益。