2011-10-03 12 views
5

私はいつも関数のプロトタイプは、ある意味ではすべてのオブジェクト間で共有されていると仮定しています。したがって、プロトタイプのプロパティの値を変更すると、そのプロトタイプを共有するすべてのオブジェクトに値の変更も反映されます。したがって、下の例では、プロパティバーがすべてのオブジェクト間で共有されるのではなく、コピーされているようです。これは正しいですか?コンストラクタのプロトタイプのプロパティは、作成されたすべてのクラスオブジェクトに単純にコピーされていますか、またはリンクによって共有されていますか?あなたがobject1.bar = 2を割り当てる場合Javascriptと関数のプロトタイプの割り当て

function foo() 
{ 
    this.bar = 1; 
} 
function derived() { } 
derived.prototype = new foo() 

object1 = new derived() 
object2 = new derived() 

object1.bar = 2; 
//but notice if I had said here derived.prototype.bar = 3, object1.bar would still equal 2 but object2.bar would equal 3 
alert(object2.bar) // this prints 1; 

答えて

12

、あなたがobject1独自のプロパティを作成している場合、このプロパティは、そのオブジェクトのインスタンスにのみ存在し、それはそのプロトタイプとは何の関係もありません。 object1

このプロパティ1の値がderived.prototype上の既存の影が、これはあなたがobject1.barを検索するとき、それは直接そのオブジェクト上の既存の値を見つけることを意味します。あなたがobject2.barを検索場合は、プロパティのルックアップは、この1つは(derived.prototype)を継承したオブジェクトを検索しますので、他の側では

は、このオブジェクトは、自身のbar性質を持っていない、それは価値1を見つけるでしょう。 --->行は継承を表現する内部[[Prototype]]リンクを表す

 
object1 
-------- 
| bar: 2 | ----------------- 
--------     |   derived.prototype 
          |  ---------- 
          |------> | bar: 1 | -- foo.prototype 
object2 (no own properties)|  ---------- | ------------------ 
--------     |      -> | constructor: foo | 
|  | -----------------       ------------------ 
--------             | 
                  v 
                ------------------ 
                | Object.prototype | 
                ------------------ 
                  | 
                  v 
                  null 

あなたのオブジェクト構造は、次のようになります。ように見えますが、2つのオブジェクトインスタンスを持っている結果、

function Animal() { 
} 
Animal.prototype.name="animal"; 

function Dog() { 
} 
Dog.prototype = new Animal 
Dog.prototype.constructor=Dog; 
Dog.prototype.name="dog"; 

object1 = new Animal(); 
object2 = new Dog(); 

(あなたはクロームデベロッパーツールやFF放火魔か...、例えばこれを確認することができます):

+0

オハイは、私がそれを再割り当てしない限り、継承されたプロパティを参照するので、一度私はそれ自身のプロパティに割り当てられますか? – rubixibuc

+0

私は今それを得ました、そのダイアグラムは多くの助けになりました、ありがとう、あなたの答えは素晴らしかったです:-) – rubixibuc

+0

@rubixibuc、右、それを割り当てたら、それは自分のプロパティになり、プロトタイプチェーンで。例えば、 'object1'と' object2'を作成した後に '[[Prototype]]'リンクを変更することはできません。 'derived.prototype'に別のオブジェクトを再割り当てしても影響はありませんそれらの2つのオブジェクトによって継承されたプロパティ – CMS

2

たとえば、コードが持っている

object1: 
    __proto__: (is ref into an Animal.prototype object) 
    constructor: function Animal() 
    name: "animal" 
    __proto__: Object (is ref into an Object.prototype object) 

object2: 
    __proto__: (is ref into an Dog.prototype object) 
    constructor: function Dog() 
    name: "dog" 
    __proto__: (is ref into an Animal.prototype object) 
     constructor: function Animal() 
     name: "animal" 
     __proto__: (is ref into an Object.prototype object) 

あなたは(たとえば)次のコードを実行します。

何が起こっ
alert(object1.name); // displayed "animal" 
alert(object2.name); // displayed "dog" 

? 1)Javascriptは、オブジェクトインスタンス内のプロパティ名(object1またはobject2)を探しました。 2)見つからない場合は、オブジェクトインスタンスprotoプロパティ(これはクラス関数のプロトタイプと同じです)で検索しました。 3)おしゃべりしていないときprotoprotoと次と次は見つからない間nameプロパティと他protoが見つかりました。検索プロパティの結果として見つかった場合は、値が返され、見つからなければundefinedが返されます。

object2: 
    name: "doggy" 
    __proto__: (is ref into an Dog.prototype object) 
    constructor: function Dog() 
    name: "dog" 
    __proto__: (is ref into an Animal.prototype object) 
     constructor: function Animal() 
     name: "animal" 
     __proto__: (is ref into an Object.prototype object) 

プロパティを直接インスタンスオブジェクトに割り当てられていますが、プロトタイプオブジェクトは変更されません:あなたはobject2はのために持っている結果

object2.name = "doggy"; 

:あなたは、次のコードを実行した場合に何が起こった

。そして、あなたが実行したとき:|: 1)

Animal.prototype.secondName="aaa"; 
alert(object1.secondName); // displayed "aaa" 
alert(object2.secondName); // displayed "aaa" 
Animal.prototype.secondName="bbb"; 
alert(object1.secondName); // displayed "bbb" 
alert(object2.secondName); // displayed "bbb" 
// but 
Animal.prototype.secondName="ccc"; 
object1.secondName="ddd"; 
alert(object1.secondName); // displayed "ccc" 
alert(object2.secondName); // displayed "ddd" 

2)

alert(object1.name); // displayed "animal" 
alert(object2.name); // displayed "doggy" 

は、作成する必要がある場合は変更は、あなたが次のalgoritmsからいずれかを使用することができ、クラスの財産を共有しましたファンクションクラスのプロトタイプにタイプobjectのプロパティを作成し、このオブジェクトのプロパティに値を割り当てます。

Animal.prototype.propObject={thirdName:"zzz"}; 
alert(object1.propObject.thirdName); // displayed "zzz" 
alert(object2.propObject.thirdName); // displayed "zzz" 
Animal.prototype.propObject.thirdName="yyy"; 
alert(object1.propObject.thirdName); // displayed "yyy" 
alert(object2.propObject.thirdName); // displayed "yyy" 
object1.propObject.thirdName="xxx"; 
alert(object1.propObject.thirdName); // displayed "xxx" 
alert(object2.propObject.thirdName); // displayed "xxx" 
object2.propObject.thirdName="www"; 
alert(object1.propObject.thirdName); // displayed "www" 
alert(object2.propObject.thirdName); // displayed "www" 
+0

きちんと説明されています。 –

関連する問題