Domanda

La mia comprensione è che "hasOwnProperty" restituisce true se l'oggetto ha un dato membro senza controllare la catena del prototipo. Ma quando eredito da un altro oggetto, vedo tutti i membri nell'ultimo oggetto stesso.

Considera il seguente esempio:

var Object1 = function (param) {
    this.prop1 = "p1 " + param;
    this.prop2 = "p2 " + param;
};

var Object2 = function (param) {
    Object1.apply(this, arguments);
    this.prop3 = 'p3' + param;
};

Object2.prototype = new Object1();

var b = new Object2('this is Object 2');

for (var v in b)
    print(v + ": " + b[v] + (b.hasOwnProperty(v)?' (own)':' (inherited)'));

Questo codice stampa:

--prop1: p1 this is Object 2 (own)
--prop2: p2 this is Object 2 (own)
--prop3: p3this is Object 2 (own)

Se guardo il debugger vedo:

b
  Object2
    prop1: "p1 this is Object 2"
    prop2: "p2 this is Object 2"
    prop3: "p3this is Object 2"
    __proto__: Object1

Ma, id rimuovo la riga apply, tutto ha più senso, ma l'oggetto base non è inizializzato:

--prop3: p3this is Object 2 (own)
--prop1: p1 undefined (inherited)
--prop2: p2 undefined (inherited)

Ora vedo nel debugger:

b
  Object2
    prop3: "p3this is Object 2"
    __proto__: Object1
      prop1: "p1 undefined"
      prop2: "p2 undefined"
      __proto__: Object

Per quanto ne so, apply è come ... eseguire il costruttore della super classe, quindi i super membri vengono inizializzati correttamente, ma a quanto pare questo cambia la forma dell'oggetto figlio.

Perché sta succedendo? Qual è il modo corretto, o almeno quello meno disordinato, di ereditare in JS?

Sto dando un'occhiata ad alcune informazioni al riguardo e, a quanto pare, ogni sviluppatore ha opinioni diverse su come farlo.

Saluti.

È stato utile?

Soluzione

apply non è affatto come eseguire il super costruttore di classi. Come costrutto, esegue qualsiasi funzione nell'ambito del primo argomento fornito . Quando si passa this alla funzione Object1 (che si esegue come funzione, non come costruttore), si passa attraverso l'ambito in cui viene eseguita la seconda funzione (Object2).

Per vedere cosa sta succedendo, prova a eseguire Object1("param") senza new:

Object1("test");

Quando eseguiamo new Object1("test"), otteniamo un oggetto simile a questo:

Object { prop1="p1 test", prop2="p2 test"}

Ma quando eseguiamo Object1("test") torniamo undefined ... e sull'oggetto uguale a this (molto probabilmente window nel caso del browser JavaScript) troviamo due nuove variabili ... prop1 e prop2.

Che cosa è successo?

La chiave qui è che:

Object1("param") !== new Object1("param");

La prima versione (Object1("param")) esegue una funzione (Object1) in alcuni ambiti già esistenti (nel JavaScript del browser l'ambito più comune è l'ambito di primo livello dove this === window). Questo è il modo in cui stanno invocando Object1 quando chiami Object1.apply(this).

La seconda versione (new Object1("param")) esegue una funzione come un costruttore , ovvero crea un nuovo oggetto e imposta this come nuovo oggetto. Se dovessimo usare la stessa funzione apply per dimostrarlo, scriveremmo Object1.apply({});

Per una delle risposte più definitive che abbia mai visto sull'argomento di come eseguire la programmazione in stile OOP giusto in un ambiente JavaScript, vedere La risposta di Bobince a questa domanda .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top