2013-10-04 7 views
7

Per questa domanda, non mi aspettavo una soluzione per risolvere qualcosa, ma vorrei capire meglio le cose ..x non è una funzione ... cosa ti aspetti Object.create a che fare con un costruttore

alcuni citazione dalle specifiche:

  • Edition 5,1 (Link)

    §15.2.3.5 Object.create (O [, Proprietà])

    01.235.

    La funzione di creazione crea un nuovo oggetto con un prototipo specificato. Quando viene chiamata la funzione di creazione, vengono eseguiti i seguenti passaggi:

    1. Se Type (O) non è Object o Null genera un'eccezione TypeError.
    2. Sia obj be il risultato della creazione di un nuovo oggetto come dall'espressione new Object() dove Object è il costruttore incorporato standard con quel nome
    3. Imposta la proprietà interna [[Prototype]] di obj su O
    4. Se l'argomento Proprietà è presente e non indefinito, aggiungere le proprie proprietà a obj come se richiamasse la funzione predefinita standard Object.defineProperties con argomenti obj e Properties.
    5. Oggetto di reso.
  • Edition 6 - progetto (Link)

    §19.1.3.2 Object.create (O [, Proprietà])

    La creazione di funzione crea un nuovo oggetto con un determinato prototipo. Quando la funzione di creare si chiama, sono prese le seguenti operazioni:

    1. Se Type (O) non è oggetto o Null un'eccezione TypeError.
      1. Let obj essere il risultato della operazione astratta ObjectCreate con argomento O.
      2. se le proprietà argomento è presente e non definito, quindi a. Restituisce il risultato dell'operazione astratta ObjectDefineProperties (obj, Properties).
      3. Oggetto di reso.

Se correttamente intesa, sia delle specifiche permettere il seguente codice da eseguire:

function F() { 
} 

var x=Object.create(F); 

// a minimal test 
alert(x.prototype.constructor===F); // true 
alert(x instanceof Function) // true 
alert(typeof x) // 'object' 

Sembra che crea un oggetto di un tipo deriva da (scusa per la scarsa terminologia ..)Function come ho provato in Firefox, e così è xnon invocabile:

x(); // x is not a function 

sto pensando perché non è vero né impedire che un costruttore per essere usato come O o semplicemente creare una valida costruttore.

Quindi mi chiedo cosa ci si aspetterebbe da Object.create con un costruttore?

+3

Mi aspetto 'Object.create' di ignorare se si tratta di un costruttore, in quanto l'algoritmo non ha bisogno di un oggetto callable. Poiché restituisce un semplice 'Object', mi aspetto anche che il risultato non sia invocabile. – Zeta

+1

A cosa serve la taglia? Ci sono ancora domande in sospeso? Vorresti che le risposte fossero più dettagliate? – Bergi

+0

È difficile sceglierne uno per contrassegnare come risposta accettata quando due hanno gli stessi voti. –

risposta

4

Sfortunatamente non funzionerà. Quello che hai è un oggetto che ha F nella sua catena di prototipi; il fatto che F sia una funzione non rende una funzione x.

Solo gli oggetti creati tramite una dichiarazione di funzione o un'espressione di funzione avranno "Funzione" come loro [[Classe]] e un metodo [[Call]], che lo rende chiamabile. Quelli sono creati secondo i passaggi dettagliati su section 13.2 of the ECMAScript 5 specification.

L'algoritmo per Object.create fa qualcosa di diverso, come puoi vedere sul preventivo. Nel tuo caso, x sarà un oggetto normale con [[Class]] "Object" e nessun metodo [[Call]]. Se provi Object.prototype.toString.call(x), riceverai "[object Object]", dove "Oggetto" è [[Classe]] di x. x instanceof Function restituisce solo true perché il costruttore Function fa parte della catena di prototipi di x (via F).

Non sono sicuro se qualcuno di ciò verrà modificato in ES6, ma suppongo che non lo farà.

+0

'instanceof' non ha nulla a che fare con [[Class]], si prega di correggere quella frase. – Bergi

+0

Molto vero @Bergi, risolto. – bfavaretto

2

Quindi mi chiedo cosa ci si aspetterebbe da Object.create con un costruttore?

mi sarei aspettato di seguire le specifiche del corso ...

sto pensando perché non è vero né impedire che un costruttore per essere usati come O

Perché dovrebbe vero? Ogni funzione del costruttore è un object (§8.6).

... o semplicemente creare un costruttore valido.

le specifiche dice che dovrebbe creare un oggetto semplice (come da new Object), la cui [[prototype]] è impostato su oggetti O. Plain esistono funzioni, non hanno un [[chiamata]] o [[costrutto]] proprietà. Avrà anche [[class]] Object, non Function.

x.prototype.constructor===F // true 
x instanceof Function // true 
typeof x // 'object' 

Sembra ha creato un oggetto di tipo deriva da (mi dispiace per il povero terminologia ..) Funzione

Da F, in realtà.Esso eredita la proprietà .prototype da F (ecco perché il tuo primo test è true) e tramite F eredita anche da Function.prototype che lo rende instanceof Function. Tuttavia, non ha una proprietà [[call]] (non è richiamabile), quindi typeof non produce "function", ma solo "object".

+0

Buon punto. Il motivo di ciò che pensavo è, poiché è una specifica di lavoro e cambia frequentemente, perché non una decisione di renderlo più utile o più severo per evitare di creare un oggetto insolito. –

+1

Nah, 'Object.create' è abbastanza ben definito e non cambierà il suo comportamento rigoroso e minimalista. Qualsiasi soluzione di "ereditarietà" per le funzioni (costruttore) sarebbe specificata in termini diversi in una funzione extra, per preservare la cruciale retrocompatibilità. – Bergi

Problemi correlati