1. ホーム
  2. javascript

[解決済み] javascriptのオブジェクトメソッドをコンストラクタ関数で宣言する場合とプロトタイプで宣言する場合【重複】。

2022-04-26 10:29:19

質問

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();