[解決済み] Javascriptでプロトタイプを使用するタイミング
質問
jsでプロトタイプメソッドを使用することが適切な場合について理解したいです。 それらは常に使用されるべきですか?それとも、それらを使用することが好ましくない、および/またはパフォーマンス上のペナルティを発生させるケースがあるのでしょうか?
jsの名前空間に関する一般的なメソッドについてこのサイトを検索してみると、ほとんどがプロトタイプに基づかない実装を使用しているようです。
クラスベースの言語から来た私にとって、プロトタイプはクラスと同じであり、私が言及した名前空間の実装は静的メソッドのようであると考え、類似点を描こうとしないのは難しいことです。
どのように解決するのですか?
プロトタイプは 最適化 .
これらをうまく使っている好例が、jQueryライブラリです。jQueryオブジェクトを取得するたびに
$('.someClass')
を使用して jQuery オブジェクトを取得するたびに、そのオブジェクトは何十もの "メソッド"を持っています。ライブラリは、オブジェクトを返すことでそれを実現することができました。
return {
show: function() { ... },
hide: function() { ... },
css: function() { ... },
animate: function() { ... },
// etc...
};
しかしそれでは、メモリ上のすべてのjQueryオブジェクトが、同じメソッドを含む何十もの名前付きスロットを、何度も何度も持つことになります。
その代わりに、これらのメソッドはプロトタイプで定義され、すべてのjQueryオブジェクトはそのプロトタイプを継承し、非常に少ない実行時コストでこれらのすべてのメソッドを得られるようにします。
jQueryがそれを正しく行う方法の重要な部分の1つは、これがプログラマーから隠されていることです。これは純粋に最適化として扱われ、ライブラリを使用する際に気にしなければならないこととして扱われることはありません。
JavaScript の問題は、裸のコンストラクタ関数の場合、呼び出し側がその前に
new
を付ける必要があり、そうしないと一般的に動作しないことです。jQueryはこの無意味なものを普通の関数の後ろに隠すことで、正しく動作するようにしています。
$
という普通の関数の後ろに隠すことで、オブジェクトがどのように実装されるかを気にする必要がないようにしています。
指定されたプロトタイプを持つオブジェクトを便利に作成できるように、ECMAScript 5 では標準的な関数である
Object.create
. それを大幅に簡略化すると、次のようになります。
Object.create = function(prototype) {
var Type = function () {};
Type.prototype = prototype;
return new Type();
};
これは、コンストラクタ関数を書いて、その関数を
new
.
プロトタイプを避けるのはどのような場合ですか?
JavaやC#のような人気のあるOO言語と比較するのが便利です。これらは2種類の継承をサポートしています。
-
インターフェース
を継承し、そこで
implement
アンinterface
のように、クラスがインターフェースの各メンバーに対して独自の実装を提供するようにします。 -
実装
を継承し、そこで
extend
aclass
で、いくつかのメソッドのデフォルトの実装を提供します。
JavaScriptでは、プロトタイプ継承は一種の の実装です。 継承の一種です。つまり、(C# や Java では) デフォルトの振る舞いを得るために基底クラスから派生し、それをオーバーライドして小さな変更を加えるような状況において、JavaScript ではプロトタイプ継承が意味を持ちます。
しかし、C#やJavaでインターフェイスを使っていたような状況であれば、JavaScriptでは特に言語的な特徴は必要ないでしょう。インターフェースを表すものを明示的に宣言する必要はありませんし、オブジェクトにそのインターフェースを実装していることを示す "implementation"をつける必要もありません。
var duck = {
quack: function() { ... }
};
duck.quack(); // we're satisfied it's a duck!
つまり、オブジェクトの "type" それぞれが "methods" を独自に定義しているならば、プロトタイプを継承する価値はないのです。その後は、各タイプのインスタンスをいくつ割り当てるかによります。しかし、多くのモジュール設計では、与えられた型のインスタンスは1つだけです。
そして実際 は、実装継承は悪であると多くの人々から言われています。 . つまり、ある型に共通する操作がある場合、それを基底/上位クラスではなく、普通の関数としてモジュールで公開し、そこに操作したいオブジェクトを渡すようにすれば、より明確になるのではないでしょうか。
関連
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] あるJavaScriptファイルを他のJavaScriptファイルにインクルードするにはどうすればよいですか?
-
[解決済み] JavaScriptでタイムスタンプを取得する方法は?
-
[解決済み】JavaScriptの比較では、どちらの等号演算子(== vs ===)を使うべきですか?
-
[解決済み】JavaScriptで文字列の出現箇所をすべて置換する方法
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
-
[解決済み] JavaScriptで次の要素/前の要素を取得しますか?
-
[解決済み] node.jsで文字列のsha1ハッシュを取得するにはどうすればよいですか?
-
[解決済み] javascriptで文字列から関数を作成する方法はありますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 文字列のn番目の出現箇所を取得するには?
-
[解決済み] モバイルWeb HTML5フレームワークの選び方【終了しました
-
[解決済み] 文字列が空白であるかどうかをチェックする
-
[解決済み] オブジェクトの配列からReactコンポーネントをレンダリングする
-
[解決済み] TypeScriptプロジェクトで既存のC#クラス定義を再利用する方法
-
[解決済み] JavaScriptでjson-objectのキーを取得する [重複].
-
[解決済み] 各オブジェクトに?重複
-
[解決済み] 文字列とラベルのローカライズとグローバリゼーションのベストプラクティス【終了しました
-
[解決済み] Prototypeを使ってtextareaを自動サイズ調整するには?
-
[解決済み] なぜjavascriptのES6 Promisesはresolve後も実行を継続するのですか?