[解決済み] javascriptのオブジェクトメソッドをコンストラクタ関数で宣言する場合とプロトタイプで宣言する場合【重複】。
質問
javascriptでオブジェクトを作成する場合、コンストラクタ関数かプロトタイプにメソッド宣言を記述することができる。 例えば、NameプロパティとBarkメソッドを持つDogクラスが欲しいとします。 Barkメソッドの宣言はコンストラクタ関数に書くことができる。
var Dog = function(name) {
this.Name = name;
this.Bark = function() {
alert(this.Name + " bark");
};
}
または、プロトタイプオブジェクトのメソッドとして置くことができます。
var Dog = function(name) {
this.Name = name;
}
Dog.prototype.Bark = function() {
alert(this.Name + " bark");
};
Dog型のオブジェクトをインスタンス化する場合、どちらの方法でも問題なく動作するようです。
var dog = new Dog("Fido");
dog.Bark(); //Both approaches show "Fido bark"
これらのアプローチのうち、どちらかを選ぶべきでしょうか? また、どちらかを使うことで何か利点があるのでしょうか? 裏を返せば、この2つのアプローチは全く同じことをやっていることになるのでしょうか? 多くの人はどちらのアプローチを好む傾向にあるのでしょうか?
ありがとうございました。
解決方法は?
この例では、プロトタイプのアプローチを使用する必要があります。一般的には、それは依存します。最初のアプローチ(コンストラクタ内でメソッドを初期化する)の主な利点は、コンストラクタ内で定義されたローカル変数をメソッドで使用することにより、クロージャを利用できることです。これらの変数はコンストラクタ関数の外からは直接アクセスできないため、事実上 private" となります。つまり、これらの変数がオブジェクトのプロパティとして定義されている場合よりも API がすっきりしていることになります。一般的な経験則をいくつか紹介します。
- コンストラクタで定義されたローカル変数を使用しないメソッドの場合(この例では使用しません)、プロトタイプのアプローチを使用します。
-
を大量に作成する場合
Dog
を使用する場合は、プロトタイプのアプローチを使用します。この方法では、すべての"インスタンス" (すなわち、?Dog
コンストラクタを使用する場合は、毎回新しい関数のセットが作成されます。Dog
コンストラクタが呼び出されると、より多くのメモリを使用することになります。 -
を少数作成するのであれば
Dog
コンストラクタでローカル変数、quot;private" を使用するとコードが改善されることがわかった場合、この方法がよいかもしれません。パフォーマンスやメモリ消費量が気になる場合は、ご自分の判断でベンチマークを実施してください。
コンストラクタのローカル変数にアクセスする必要があるメソッドのみをコンストラクタで定義し、その他のメソッドはプロトタイプに割り当てるというハイブリッドなアプローチを使用することも可能です。
例えば、以下のコードでは、コンストラクタのローカル変数を使ってこの犬が吠えた回数を記録していますが、実際の回数は非公開にしているので、吠えた回数に関するメソッドはコンストラクタの内部で定義されています。尻尾振りは吠えた回数にアクセスする必要がないので、そのメソッドはプロトタイプに定義することができます。
var Dog = function(name) {
this.name = name;
var barkCount = 0;
this.bark = function() {
barkCount++;
alert(this.name + " bark");
};
this.getBarkCount = function() {
alert(this.name + " has barked " + barkCount + " times");
};
};
Dog.prototype.wagTail = function() {
alert(this.name + " wagging tail");
};
var dog = new Dog("Dave");
dog.bark();
dog.bark();
dog.getBarkCount();
dog.wagTail();
関連
-
親子コンポーネント通信を解決する3つのVueスロット
-
[解決済み】 Uncaught TypeError : undefined のプロパティ 'replace' を読み取れない In Grid
-
JSクリックイベント - Uncaught TypeError: プロパティ 'onclick' に null を設定できません。
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] JavaScriptのオブジェクトが空であることをテストするにはどうすればよいですか?
-
[解決済み] JavaScriptのオブジェクトにキーが存在するかどうかをチェックする?
-
[解決済み] JavaScriptのオブジェクトをループスルーまたは列挙するにはどうすればよいですか?
-
[解決済み] JavaScriptでNULL、未定義、空白の変数をチェックする標準的な関数はありますか?
-
[解決済み】JavaScriptのオブジェクトの長さ
-
[解決済み】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 実装 サイバーパンク風ボタン
おすすめ
-
親子コンポーネント通信を解決する3つのVueスロット
-
JavaScriptの配列共通メソッド解説
-
vueディレクティブv-bindの使用と注意点
-
[解決済み】Uncaught SyntaxError: JSONの位置0に予期しないトークンuがあります。
-
[解決済み】gulp anythingを実行するたびに、アサーションエラーが発生します。- タスク関数を指定する必要があります
-
[解決済み】ERROR エラーです。スイッチのname属性が指定されていないフォームコントロールの値アクセッサがない
-
JSクリックイベント - Uncaught TypeError: プロパティ 'onclick' に null を設定できません。
-
モジュールのビルドに失敗しました。Error: ENOENT: no such file or directory, scandir 'D:\.... \node_modules
-
JavaScriptのgetElementById()メソッド入門
-
[解決済み】プロトタイプを使用する利点と、コンストラクタで直接メソッドを定義する利点は?重複