Domanda

Ci sono solo 3 linee di codice, ma sto avendo problemi completamente afferrare questo:

Object.create = function (o) {
    function F() {}
    F.prototype = o;
    return new F();
};
newObject = Object.create(oldObject);

( prototipale Inheritance )

  1. Object.create() inizia con la creazione di una funzione vuoto chiamato F. Sto pensando che una funzione è un tipo di oggetto. Dove si trova questo oggetto F essere conservato? Globalmente immagino.

  2. Avanti nostro oldObject, passato come o, diventa il prototipo della funzione F. Funzione (vale a dire, oggetto) F ora "eredita" dalla nostra oldObject, nel senso che la risoluzione dei nomi percorso volontà attraverso di essa. Buono, ma sono curioso di ciò che il prototipo di default è per un oggetto, oggetto? Che è vero anche per una funzione-oggetto?

  3. Infine, F viene creata un'istanza e restituito, diventando il nostro newObject. È l'operazione new strettamente necessario qui? Non F già a disposizione quello che ci serve, o c'è una differenza fondamentale tra oggetti-funzione e non-oggetti-funzione? Chiaramente non sarà possibile avere una funzione di costruzione utilizzando questa tecnica.

Che cosa succede la prossima volta Object.create() si chiama? È la funzione F globale sovrascritto? Sicuramente non viene riutilizzato, perché ciò alterare oggetti precedentemente configurati. E cosa succede se più thread chiamano Object.create(), non v'è alcun tipo di sincronizzazione per evitare condizioni di gara su F?

È stato utile?

Soluzione

  

1) Object.create () inizia da   creando una funzione vuoto chiamato F.   Sto pensando che una funzione è un genere   dell'oggetto. Dov'è questo oggetto F   essere memorizzati? Globalmente immagino.

No, è memorizzato sulla portata locale della funzione Object.create, ogni volta che si richiama Object.create questa funzione F verrà ricreato.

Si potrebbe anche creare una memoria-efficiente implementazione di più, memorizzando F su una chiusura, e riutilizzarlo:

if (typeof Object.create !== "function") {
  Object.create = (function () {
    function F() {} // created only once
    return function (o) {
      F.prototype = o; // reused on each invocation
      return new F();
    };
  })();
}
  

2) Avanti nostro oldObject, passato come o,   diventa il prototipo della funzione F.   Funzione (cioè, oggetto) F ora   "eredita" dalla nostra oldObject, nel   percepire che instraderà la risoluzione dei nomi   attraverso esso. Buono, ma sono curioso di ciò che   il prototipo di default è per un   oggetto Oggetto? Che è vero anche per la   un oggetto-funzione?

Tutti gli oggetti hanno una proprietà interna che costruisce la catena di prototipi, questa struttura è conosciuta come [[Prototype]], è una proprietà interna, anche se alcune implementazioni consentono di accedere ad esso, come Mozilla, con la proprietà obj.__proto__.

Il [[Prototype]] di default quando si crea un nuovo oggetto, vale a dire var obj = {}; è Object.prototype.

Tutte le funzioni hanno una proprietà prototype, questa proprietà viene utilizzata quando una funzione viene usato come un Constructor , invocato con l'operatore new.

Una nuova istanza dell'oggetto è creato dietro le quinte, e questo oggetto [[Prototype]] è impostato per la sua proprietà prototype Costruttori.

  

3) Infine, F e viene creata un'istanza   tornato, diventando il nostro newObject. È   l'operazione "nuova" strettamente necessario   Qui? Non F già fornire ciò   abbiamo bisogno, o c'è una critica   differenza tra oggetti-funzione   e non-oggetti-funzione? chiaramente   non sarà possibile avere un   funzione di costruzione che utilizza questo   tecnica.

Sì, l'operatore new è essenziale in questo metodo.

L'operatore new è il modo unico standard per impostare la proprietà interna [[Prototype]] di un oggetto, se siete curiosi di sapere come funziona, si può dare uno sguardo al [[Construct]] funzionamento interno.

  

Che cosa succede la prossima volta   Object.create () si chiama? è globale   funzione F sovrascritto? Sicuramente è   non riutilizzato, perché ciò alterare   precedentemente configurato oggetti. E   cosa accade se più thread chiamano   Object.create (), c'è qualche sorta di   la sincronizzazione per evitare gara   condizioni F?

La prossima volta Object.create viene richiamato, una nuova funzione F locale viene creata un'istanza solo nell'ambito della chiamata al metodo, non si deve preoccupare di condizioni di gara .

Si noti che questa implementazione è conforme a malapena il Object.create descritto nella ECMAScript 5th Edition specifiche , a quel metodo, si potrebbe passare un descrittore di proprietà per inizializzare l'oggetto.

Tutti i produttori di browser stanno attuando esso (già disponibile su Firefox 3.7 Alpha, ultima Wekit nightly build e Chrome 5 beta), quindi vi consiglio di almeno per verificare se esistono un'implementazione nativa prima di override di esso.

Altri suggerimenti

1) Una funzione è infatti un tipo di oggetto. Un oggetto funzione con identificativo F viene creata ogni volta Object.create viene chiamato, ed è accessibile solo mediante tale identificatore all'interno di tale esecuzione Object.create. Pertanto, ogni volta che viene chiamato Object.create, si ottiene un diverso F funzione di oggetto. Questa funzione di oggetto vite sulla come proprietà constructor dell'oggetto restituito da Object.create.

2)

  

F ora "eredita" dalla nostra oldObject,   nel senso che la risoluzione dei nomi volontà   percorso attraverso di essa

Questo non è propriamente corretto. Assegnazione di un someObject oggetto alla proprietà prototype di una funzione significa solo che il prototipo di un oggetto futuro creato da chiamare questa funzione come un costruttore sarà someObject.

3) La new è assolutamente vitale per questa tecnica. Solo chiamando una funzione come un costruttore fa produrre un nuovo oggetto, e il prototipo di quell'oggetto (che non è generalmente accessibile) è impostato alla proprietà prototype della funzione di costruzione. Non c'è altra (standardizzato) modo per impostare il prototipo di un oggetto.

Infine, JavaScript nei browser è single threaded, quindi condizioni di gara, come si descrive non sono possibili.

Il grande equivoco è che F ha portata globale. Si dichiara nel corpo di Object.create e conseguentemente è solo in ambito entro quel blocco metodo.

  

> Chiaramente non sarà possibile avere una funzione di costruzione utilizzando questa tecnica.

La tecnica è già un costruttore di oggetto in quanto restituisce nuova F (), ma non i valori delle proprietà può essere impostata come per dire uomo nuovo ( 'John', 'Smith'). Tuttavia, se il codice Object.create viene modificato, è possibile esemplificazione. Ad esempio l'oggetto sarah seguito possono essere costruite e un'istanza utilizzando Object.creator, e erediterà il metodo getName.

var girl = {
   name: '',
   traits: {},
   getName: function(){return this.name}
}

var sarah = Object.creator(girl, 'Sarah', {age:29,weight:90})

L'oggetto sarah sarà quindi composto da proprie caratteristiche {nome: 'Sarah', tratti: {Età: 9, peso: 49}}, e il prototipo ereditato sarah.getName () produrrà 'Sarah'

Il seguente metodo si basa sulle proprietà propri enumerazione con 'per (prop in o)' in ordine di creazione. Anche se non garantita da specifiche ECMA, questo esempio (e qualche più complesso) ha lavorato per tutti i principali browser (4) testato, providied hasOwnProperty () è stato utilizzato, altrimenti no.

Object.creator = function(o) {
   var makeArgs = arguments 
   function F() {
      var prop, i=1, arg, val
      for(prop in o) {
         if(!o.hasOwnProperty(prop)) continue
         val = o[prop]
         arg = makeArgs[i++]
         if(typeof arg === 'undefined') break
         this[prop] = arg
      }
   }
   F.prototype = o
   return new F()
}

L'ECMA Object.create ufficiale ha un secondo parametro opzionale, propertiesObject, che può istanziare i valori delle proprietà, ma è un oggetto piuttosto che il solito elenco, e sembra scomodo da utilizzare. Per esempio. Credo che: -

o2 = Object.create({}, { p: { value: 42, writable: true, enumerable: true, configurable: true } });

è equivalente alla vecchia maniera molto più semplice: -

o2 = new function(p) { this.p=p }(42)

e

o2 = Object.creator({p:''}, 42)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top