2011-10-03 14 views
5

Ho sempre pensato che il prototipo di una funzione fosse condiviso tra tutti gli oggetti, in un certo senso per riferimento. Quindi, se si modifica il valore di una proprietà del prototipo, anche tutti gli oggetti che condividono quel prototipo modificano i valori. Quindi, ad esempio, sotto sembra che invece della barra delle proprietà sia condivisa tra tutti gli oggetti, essa viene copiata. È giusto? Le proprietà del prototipo del costruttore sono semplicemente copiate in tutti gli oggetti di classe man mano che vengono create o sono condivise dal collegamento?Javascript e assegnazione prototipo di funzione

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; 

risposta

12

Quando si assegna object1.bar = 2, si sta creando un proprietà su object1, questa proprietà esistere solo in quel caso oggetto, e non ha nulla a che fare con il suo prototipo.

La struttura, situata sulla object1 volontà ombra il valore di quella esistente su derived.prototype, questo significa che quando si ricerca object1.bar, troverà un valore direttamente esistente su tale oggetto.

D'altra parte, se si ricerca object2.bar, questo oggetto non dispone di una propria bar proprietà, quindi la ricerca di proprietà cercherà sull'oggetto questa eredita da (derived.prototype) e sarà trovare il valore 1.

La vostra struttura oggetto simile a questa:

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

Dove le ---> linee indicano il [[Prototype]] link interno che esprime eredità.

+0

ohhh, ha perfettamente senso, quindi finché non lo riassegno, si riferisce alla proprietà ereditata, quindi una volta assegnata diventa una proprietà? – rubixibuc

+0

Ho capito, lo schema mi è stato di grande aiuto, grazie mille, la tua risposta è stata fantastica :-) – rubixibuc

+0

@rubixibuc, a destra, una volta assegnato, diventerà una proprietà e * ombreggia * qualsiasi valore nella catena del prototipo. Si noti inoltre che il collegamento '[[Prototype]]' non può essere modificato dopo la creazione di un oggetto, ad esempio, dopo aver creato 'object1' e' object2', si riassegna un oggetto diverso a 'derived.prototype' questo non influisce le proprietà ereditate da questi due oggetti. – CMS

2

Ad esempio, si dispone di codice:

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

Come risultato si dispone di due istanze di oggetti, che sembrava (è possibile controllare questo, ad esempio in Chrome devtools o FF Firebug o ...):

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) 

Quando si esegue codice successivo (per esempio):

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

Che cosa è successo? 1) Javascript ha cercato il nome della proprietà nell'istanza dell'oggetto (in object1 o object2). 2) Quando non è stato trovato, ha cercato nell'istanza dell'oggetto proprietà proto (è lo stesso di un prototipo di funzione di classe). 3) Quando non funziona guardò in proto di proto e il prossimo e il prossimo mentre non trovato name proprietà e altri proto trovati. Se viene trovato come risultato della proprietà di ricerca, viene restituito il valore, se non trovato, quindi restituito undefined.

Che cosa è successo, se si esegue il codice seguente:

object2.name = "doggy"; 

Come risultato si ha per oggetto2:

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) 

proprietà viene assegnato direttamente in istanza di un oggetto, ma prototipo oggetto rimane invariato.E quando si esegue:

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

quando si ha bisogno per creare | cambiamento condiviso proprietà di classe, è possibile utilizzare uno a partire dal prossimo algoritmi: 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) Crea una proprietà di tipo object in prototipo di classe di funzione e assegna valori alle proprietà di questo oggetto.

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

Ben spiegato. –

Problemi correlati