2015-10-01 15 views
5

In realtà non sono sicuro di essermi imbattuto in un comportamento indesiderato in javascript o se si tratta di un comportamento intenzionale.Comportamento javascript dispari per il controllo della chiave "costruttore" nell'oggetto

il codice seguente genera in una vera dichiarazione:

var test= {"test":1} 
document.write("constructor" in test);  

http://jsfiddle.net/xyatxm2g/2/

Se cambio al seguente codice, restituisce false come dovrebbe:

var test= {"test":1} 
document.write(test.hasOwnProperty("constructor")); 

http://jsfiddle.net/fg06ovvc/2/

risposta

9

hasOwnProperty method , come dice il nome, guarda nell'oggetto per vedere se ha la proprietà stessa.

Ma quando si utilizza 'propertyName' in test, non si sta solo esaminando le proprietà dell'oggetto stesso, ma anche le proprietà che provengono dall'ereditarietà.

In tal caso, constructor è una proprietà che risiede all'interno di Object's prototype, quindi tutti gli oggetti hanno quella proprietà, poiché tutti ereditano da Object.

Citazione da MDN

Ogni oggetto discendeva da Object eredita il metodo hasOwnProperty. Questo metodo può essere utilizzato per determinare se un oggetto ha la proprietà specificata come proprietà diretta di tale oggetto; a differenza dello in operator, questo metodo non controlla la catena del prototipo dell'oggetto .

+0

Quindi, se voglio per verificare la presenza di una chiave in un dizionario, dovrei sempre preferiscono usare il metodo '' 'hasOwnProperty'''? – fsociety

+0

@barsch Sì. Ecco perché per iterare su tutte le chiavi effettive di un oggetto (se 'Object.keys (obj)' non è disponibile), fai 'for (var key in obj) {if (obj.hasOwnProperty (key)) {doSomethingWithKey (chiave); }} '. – GregL

+0

@barsch Se si stanno mirando solo ai nuovi browser, è possibile utilizzare anche [il Tipo di mappa] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map). In futuro, utilizzando gli oggetti JavaScript standard, le mappe diventeranno probabilmente meno popolari ora che abbiamo un'opzione più specializzata. –

2

Dal MDN documentation:

proprietà ereditate
l'operatore in ritorna vero immobili a catena di prototipi.
"toString" in {}; // returns true

considerando il metodo hasOwnProperty() controlla solo le proprietà direttamente sull'oggetto, non ereditata (cioè non sulla catena prototipo).

1

Dopo la documentazione MDN, non è un campo enumerabile.

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable

È possibile eseguire test seguente:

var obj = {"t": 23}; 
obj.propertyIsEnumerable("t") 

risultati: true

obj.propertyIsEnumerable("constructor") 

risultati: false

C'è un esempio completo su questo documento, ai sensi della sezione :

diretto contro le proprietà ereditate

+0

C'è una domanda correlata su http://stackoverflow.com/questions/10968962/hasownproperty-vs-propertyisenumerable – apast

1

Penso che possa essere un comportamento normale qui che l'operatore key in object sta cercando attraverso la catena di prototipi e il ritorno vero per Object.prototype.constructor. Vedi questa discussione - si passa su un argomento correlato.

How do I check if an object has a property in JavaScript?

Problemi correlati