2016-07-12 3 views
1

Personinstanceは、例えば、person1nameheightなどのPerson.prototypeで定義されてarrayはなく、他のプロパティでプロパティjobsを、変更することができる、なぜ私は混乱しています。これは、person2person1propertiesを修正しようとした後にPerson.prototypeからプロパティを呼び出すときに発生します。私はどんな考えや考えにも感謝します。ありがとうございました。Javascript:インスタンスが配列を変更できますが、プロトタイプで定義されている他のプロパティは変更できないのはなぜですか?

function Person(){ 

} 

Person.prototype = { 
    constructor : Person, 
    name: "Hello", 
    height: 6, 
    jobs: ['developer', 'student'], 
    getInfo: function(){ 
     alert("My name is "+this.name+" and my height is: "+this.height+" feet"); 
    } 
} 

var person1 = new Person(); 
person1.height = 5; 
person1.name = "World"; 
person1.jobs.push('cook'); 
alert(person1.jobs); //developer, student, cook 
alert(person1.height); //5 
alert(person1.name); //World 

var person2 = new Person(); 
alert(person2.height); //6 
alert(person2.jobs); //developer, student, cook 
alert(person2.name); //Hello 
+1

PersonのコンストラクタをPersonに設定するのはなぜですか? –

+0

@Bálint:これはJavaScriptがプロトタイプオブジェクトの 'constructor'プロパティを定義しているからです(それほど難しくありません)。 –

+0

@ T.J.Crowder 'Person.prototype = {...}'を書くと、コンストラクタはPerson関数であることが既に解読されています。 –

答えて

1

あなたは

person1.height = 5; 

を行うときにオブジェクトperson1は、そのプロトタイプから継承heightを隠して自身heightプロパティを取得するために参照するため。

しかし、ときに実行します。

person1.jobs.push('cook'); 

あなたはjobsへを割り当てるじゃない、あなただけのjobsは、(配列)を参照するものの状態を変更しています。プロトタイプのものを変更しています。

あなたがやった場合:当社heightの例のようになります

person1.jobs = ['cook']; 

person1自身jobs財産になるだろう。あなたはプロトタイプが持っていたというジョブを保持する場合は、最初の配列をコピーすることができます:

person1.jobs = person1.jobs.slice(); 
person1.jobs.push('cook'); 

だが、何がメモリ内で起こっているのを見てみましょう:あなたはPerson機能やオブジェクトを作成した

そのPerson.prototype性質上、我々はメモリでこれを持っている:

 
     +------------------------------------------+ 
     |           | 
     |           | 
     \ +------------+       | 
Person---->| (function) |       | 
      +------------+  +---------------+ |    
      | prototype |---->| (object) | |    
      +------------+  +---------------+ |    
           | constructor |---+    
           | getInfo  |------>(not shown) 
           | name: "Hello" |     
           | height: 6  |  +----------------+ 
           | jobs   |----->|  (array) | 
           +---------------+  +----------------+ 
                | 0: "developer" | 
                | 1: "student" | 
                +----------------+ 

をその後、我々が行う

var person1 = new Person(); 

と我々は、この持っている:あなたがこれを行うと

 
     +----------------------------------------------+ 
     |            | 
     |            | 
     \ +------------+        | 
Person---->| (function) |        | 
      +------------+   +---------------+ |    
      | prototype |-------->| (object) | |    
      +------------+  /+---------------+ |    
           | | constructor |---+    
           | | getInfo  |------>(not shown) 
           | | name: "Hello" |     
           | | height: 6  |  +----------------+ 
           | | jobs   |----->|  (array) | 
           | +---------------+  +----------------+ 
           |       | 0: "developer" | 
           |       | 1: "student" | 
           |       +----------------+ 
      +---------------+ | 
person1--->| (object) | | 
      +---------------+ | 
      | [[Prototype]] |---+ 
      +---------------+ 

は:やっ

 
           (to Person.prototype) 
      +---------------+ | 
person1--->| (object) | | 
      +---------------+ | 
      | [[Prototype]] |---+ 
      | height: 5  | 
      +---------------+ 

しかし:

person1.height = 5; 

person1が取得するその自身heightを(他のすべてが同じまま) person1.jobs.push('cook');は配列の状態を変更するだけですjobsポイントへ:jobsの場合

 
     +----------------------------------------------+ 
     |            | 
     |            | 
     \ +------------+        | 
Person---->| (function) |        | 
      +------------+   +---------------+ |    
      | prototype |-------->| (object) | |    
      +------------+  /+---------------+ |    
           | | constructor |---+    
           | | getInfo  |------>(not shown) 
           | | name: "Hello" |     
           | | height: 6  |  +----------------+ 
           | | jobs   |----->|  (array) | 
           | +---------------+  +----------------+ 
           |       | 0: "developer" | 
           |       | 1: "student" | 
           |      +->| 2: "cook"  | 
           |      | +----------------+ 
      +---------------+ |      | 
person1--->| (object) | |      | 
      +---------------+ |   NOTE WHAT | 
      | [[Prototype]] |---+   CHANGED ----+ 
      | height: 5  | 
      +---------------+ 
+1

ありがとうございました。 –

0

は、オブジェクトを変異しているのではなく、オブジェクトを再度割り当てます。

person1.height = 5;の場合は、割り当てています。したがって、person1に割り当てられますが、プロトタイプには割り当てられません。 jobsの場合は、突然変異しているだけなので、エフェクトが表示されます。詳細については、プロトタイプ継承を参照してください。

関連する問題