2011-12-09 13 views
23

consideri un oggetto con una catena di prototipi:instanceof equivalente per catene Object.create e prototipo

var A = {}; 
var B = Object.create(A); 
var C = Object.create(B); 

Come controllare in runtime se C ha A nella sua catena di prototipi?

instanceof non si adatta in quanto è progettato per funzionare con le funzioni di costruzione, che non sto usando qui.

risposta

21

La mia risposta sarà breve ...

è possibile utilizzare il metodo isPrototypeOf, che sarà presente nel caso in cui l'oggetto eredita dal prototipo oggetto, come il vostro esempio.

esempio:

A.isPrototypeOf(C) // true 
B.isPrototypeOf(C) // true 
Array.prototype.isPrototypeOf(C) // false 

Maggiori informazioni può essere letto qui: Mozilla Developer Network: isPrototypeOf

+1

+1 Soluzione semplice. Sebbene i tuoi esempi siano completamente corretti, sarebbe 'Array.prototype.isPrototypeOf (C)' per verificare se 'C' è un array (ho trovato il tuo ultimo esempio un po 'ambiguo - usare' isPrototypeOf' su una funzione di solito non è ciò che vuoi). – pimvdb

+0

Hai perfettamente ragione, non volevo perdere troppo tempo poiché una risposta era già stata data in quel momento, quindi non ho pensato troppo agli esempi, il mio obiettivo era solo quello di mostrare il metodo disponibile .. comunque correggerò l'esempio dato con la tua risposta, poiché come hai detto e sono d'accordo, il mio ultimo esempio è ambiguo, grazie per l'avviso =) – Couto

+0

Solo una domanda veloce: come è possibile che l'oggetto non erediti da Object? Qualsiasi oggetto ha un riferimento [[Prototipo]] che attraverso una catena di prototipi porta infine a Object.prototype. –

4

È possibile ripetere l'iterazione attraverso la catena del prototipo chiamando Object.getPrototypeOf in modo ricorsivo: http://jsfiddle.net/Xdze8/.

function isInPrototypeChain(topMost, itemToSearchFor) { 
    var p = topMost; 

    do { 

     if(p === itemToSearchFor) { 
      return true; 
     } 

     p = Object.getPrototypeOf(p); // prototype of current 

    } while(p); // while not null (after last chain) 

    return false; // only get here if the `if` clause was never passed, so not found in chain 
} 
+0

+1 stava per inviare un quasi identico * * risposta, anche con il fai-while' ', che I don' vedere troppo spesso Ma il tuo è trasformato in una funzione, che è più bella. – RightSaidFred

+0

@RightSaidFred: Divertente, stavo anche pensando al fatto che stavo usando la parola chiave 'do' che non faccio quasi mai. – pimvdb

+0

Mi sorprende che non esista una proposta 'Object.hasPrototype' per ES6 che faccia esattamente ciò che fa la tua funzione. Sembra un complemento naturale 'Object.create' come' instanceof' è 'nuovo Costruttore'. Potrebbe persino accettare una funzione come secondo argomento, che userebbe il 'prototipo' della funzione come target. – RightSaidFred