7

そのため、コンストラクターのプロトタイプ プロパティにメソッドを設定して、複数の異なるインスタンスを持たないようにする必要があることを見たり聞いたりしました。しかし、プロパティ自体はどうですか? ベストプラクティスはどれですか? その場合、コンストラクターは常に空であるべきではありませんか?

function Gadget(name, color) {
     this.name = name;
     this.color = color;
     this.whatAreYou = function(){
       return 'I am a ' + this.color + ' ' + this.name;
     }
}

これは実際にあるべきですか...?

function Gadget(name,color){}

Gadget.prototype.name = name;
Gadget.prototype.color = color;
Gadget.prototype.whatAreYou = function() {
   return 'I am a ' + this.color + ' ' + this.name;
};
4

2 に答える 2

8

プロトタイプに設定すると、プロパティはすべてのインスタンスで共有されます。通常、あなたが望むものではありません。II は、これについてhttp://js-bits.blogspot.com/2014/10/understanding-prototyping-inheritance.htmlでブログを書きました。通常、各ガジェットに独自の名前と色を付けます。あなたが提案したコードでそれをどのように行いますか?

ちなみに、あなたが提案したコードには未定義の変数(名前、色)があります

通常の方法は、プロトタイプにメソッドを設定し、オブジェクト自体に通常の値を設定することです。プロパティをすべてのインスタンスで共有したくない場合を除き、それは静的型付き言語で静的プロパティと呼ばれるもののようなものです。

これが例です

function Gadget(name,color){
    this.name = name;
    this.color = color;
    // Since all gadgets in on the prototype, this is shared by all instances;
    // It would more typically be attached to Gadget.allGadgets instead of the prototype
    this.allGadgets.push(this);
    // Note that the following would create a new array on the object itself
    // not the prototype
    // this.allGadgets = [];

}

Gadget.prototype.allGadgets = [];
Gadget.prototype.whatAreYou = function() {
    return 'I am a ' + this.color + ' ' + this.name;
};

覚えておくべき重要な概念は、書き込み (割り当て) は、プロトタイプではなく、常にオブジェクト自体に適用されるということです。ただし、読み取りは、そのプロパティを探してプロトタイプ チェーンをたどります。

あれは

function Obj() {
   this.map = {};
}

function SharedObj() {}
SharedObj.prototype.map = {};

var obj1 = new Obj();
var obj2 = new Obj();
var shared1 = new SharedObj();
var shared2 = new SharedObj();

obj1.map.newProp = 5;
obj2.map.newProp = 10;
console.log(obj1.map.newProp, obj2.map.newProp); // 5, 10

// Here you're modifying the same map
shared1.map.newProp = 5;
shared2.map.newProp = 10;
console.log(shared1.map.newProp, shared2.map.newProp); // 10, 10

// Here you're creating a new map and because you've written to the object directly    
// You don't have access to the shared map on the prototype anymore
shared1.map = {};
shared2.map = {};
shared1.map.newProp = 5;
shared1.map.newProp = 10;
console.log(shared1.map.newProp, shared2.map.newProp); // 5, 10
于 2013-04-01T17:49:12.877 に答える
2

プロパティの場合、これは期待どおりに動作しない場合があります。すべてのインスタンスで同じ関数参照を共有する必要があるため、メソッドはプロトタイプのように宣言する必要があります。通常、プロパティはインスタンスごとに異なります。プリミティブを扱っているときはこれに気付かないかもしれませんが、オブジェクト (または配列など) であるプロパティの「奇妙な」動作に遭遇するでしょう。

function Test(){}
Test.prototype.foo = {bar: 1};
Test.prototype.baz = 1;

var one = new Test();
var two = new Test();
one.foo.bar = 3;
two.foo.bar === 3; // true, because of object reference
// BUT:
one.baz = 3;
two.baz === 1; // true
于 2013-04-01T17:52:36.613 に答える