2012-04-13 13 views
9

Ho letto gli spessori di Crockford per impedire la sovrascrittura dei prototipi e capisco che a volte non è la soluzione definitiva. Capisco anche che ES5 Shim potrebbe essere una valida alternativa a questo. Leggo anche this post which provides a more robust, secure alternative.Capire lo shim Object.create di Crockford

Ancora, mi piacerebbe sapere qual è il suo spessorato Object.create "dicendo" e quindi "facendo". Qualcuno può dirmi se i miei commenti di spiegazione sono giusti?

if (typeof Object.create === 'undefined') { 
//If the browser doesn't support Object.create 

    Object.create = function (o) { 
    //Object.create equals an anonymous function that accepts one parameter, 'o'. 

    function F() {}; 
    //Create a new function called 'F' which is just an empty object. 

    F.prototype = o; 
    //the prototype of the 'F' function should point to the 
    //parameter of the anonymous function. 

    return new F(); 
    //create a new constructor function based off of the 'F' function. 
    }; 
} 

//Then, based off of the 'Lost' example in the Crockford book... 

var another_stooge = Object.create(stooge); 

//'another_stooge' prototypes off of 'stooge' using new school Object.create. 
//But if the browser doesn't support Object.create, 
//'another_stooge' prototypes off of 'stooge' using the old school method. 

In questo modo, il prototipo dell'oggetto 'fantoccio' non possono essere sovrascritti quando accresciamo roba da 'another_stooge'. Non c'è bisogno di resettare il prototipo 'stooge' usando 'costruttore'.

Grazie in anticipo,

-k

risposta

14
if (typeof Object.create !== 'function') { 
    Object.create = function (o) { 
     function F() {} 
     F.prototype = o; 
     return new F(); 
    }; 
} 
var oldObject={prop:'Property_one' }; // An object 
var newObject = Object.create(oldObject); // Another object 

Nell'esempio precedente abbiamo creato un nuovo oggetto newObject utilizzando create metodo che è una funzione di membro di Object oggetto che abbiamo aggiunto nell'oggetto Object in precedenza nel nostro esempio (di Crockford). Quindi, fondamentalmente quello che fa è che, il metodo create dichiara una funzione every function is a first class object in javascript, un oggetto vuoto every function is a first class object in javascript e quindi abbiamo ereditato il prototipo di o (in questo caso oldObject passato come parametro del metodo create) e infine abbiamo restituito il nuovo oggetto (un'istanza di F) utilizzando return new F(); alla variabile newObject, quindi ora newObject è un oggetto che ha ereditato lo oldObject. Ora se scrivi console.log(newObject.prop); allora verrà emesso Property_one perché il nostro oggetto ha ereditato lo oldObject ed è per questo che abbiamo il valore prop come Property_one. questo è noto come eredità prototipica.

si deve passare un oggetto come parametro del metodo create

+0

A-ha! Penso di aver capito. Grazie Sheikh ... il tuo aiuto è molto apprezzato !!! – kaidez

+0

Siete i benvenuti :-) –

0

Tutto ciò che fa è creare un nuovo costruttore dell'oggetto, che è F, è quindi assegnare l'oggetto passato alla proprietà constructor prototipo in modo che il nuovo oggetto creato con la Il costruttore F eredita questi metodi.

E 'quindi utilizzare il costruttore per restituire un oggetto di nuova inizializzare

(nuovo) = F (> F.prototype) Ma quello Crockford riuscire a riassegnare il costruttore correttamente come normalmente il nuovo costruttore dell'oggetto dovrebbe essere la stessa come costruttore di oggetti da cui eredita.

+0

Ciao gillesc. Grazie per aver risposto! Quindi, quando viene usato, vuol dire che il prototipo del costrut- tore deve essere resettato? Qualcosa come: stooge.prototype.constructor = stooge; Grazie ancora! – kaidez

0

Sui vostri commenti:

> //Object.create equals an anonymous function that accepts one parameter, 'o'. 

meglio dire che una funzione viene assegnato al create proprietà di Object. Tutte le funzioni possono essere considerate anonime, solo che alcune sono assegnate a proprietà o variabili nominate, altre no.

> //Create a new function called 'F' which is just an empty object. 

Dichiarare una funzione. Sì, è anche un oggetto.

>  F.prototype = o; 
>  //the prototype of the 'F' function should point to the 
>  //parameter of the anonymous function. 

Un riferimento o è assegnato ad F.prototype è un po 'più breve per scrivere.

>  //create a new constructor function based off of the 'F' function. 

No, deve essere "Restituire un'istanza di F". Quindi l'oggetto restituito ha un interno [[Prototype]] che fa riferimento all'oggetto passato alla funzione. La parte disordinata è che è stata creata una funzione F inutile per eseguire il trucco e il costruttore dell'oggetto restituito non avrà un valore utile in quanto fa riferimento allo F vuoto.

Non che la proprietà del costruttore sia comunque molto affidabile o particolarmente utile normalmente.

In questo modo, il prototipo dell'oggetto 'fantoccio' non possono essere sovrascritti quando accresciamo roba da 'another_stooge'. Non è necessario reimpostare il prototipo "stooge" con il "costruttore".

Questa è una strana affermazione. * another_stooge * ha stooge come privato , non eredita da stooge.prototype ma da stooge.[[Prototype]].

Se si desidera another_stooge ereditare da stooge.prototype, utilizzare Object.create(stooge.prototype) o Object.create(new stooge()), il primo è probabilmente più adatto.

Spero che tutto abbia un senso.

+0

Ciao RobG. Grazie per aver risposto! Devo rileggere per comprendere appieno la sintassi ma certamente ne so più di quanto non abbia fatto un'ora fa. Grazie ancora! – kaidez

0

Ci sono due trucchi qui:

  1. F non è una funzione semplice, è un costruttore.
  2. "F.prototype" è solo una proprietà, non fa nulla con l'ereditarietà in questo momento. Il vero trucco è che quando usiamo "nuova F()", il "nuovo" crea un nuovo oggetto, chiama il costruttore (che non fa nulla qui) E imposta il campo "prototipo" interno del nuovo oggetto con il valore di "F.prototype", quindi l'oggetto restituito erediterà da "o".

Quindi penso, che:

  • F è un costruttore
  • F non è ereditare da o
  • "nuova F" (che è l'oggetto restituito) è ereditare da o
-1

Suppongo che denominare la funzione interna come Object anziché F rende l'oggetto risultante più simile a quello Object.create() w potrebbe creare.

if (typeof Object.create !== 'function') { 
    Object.create = function (o) { 
     function Object() {} 
     Object.prototype = o; 
     return new Object(); 
    }; 
}