Verifica se esiste una chiave in un oggetto JavaScript?


2973

Come posso verificare se esiste una chiave particolare in un oggetto o in una matrice JavaScript?

Se una chiave non esiste e provo ad accedervi, restituirà false? O lanciare un errore?


2
Tutto (quasi tutto) in JavaScript è un oggetto o può essere lanciato come tale. È qui che nascono array pseudo associativi proprio come ha sottolineato @PatrickM.
Andrew Larsson,

questo benchmark jsben.ch/#/WqlIl offre una panoramica dei modi più comuni per ottenere questo controllo.
EscapeNetscape,

una soluzione rapida, di solito cerco property.key = property.key || 'some default value', nel caso in cui volessi che quella chiave esistesse con un certo valore per essa
RGLSV

Risposte:


4121

Il controllo della non definizione non è un modo accurato di verificare l'esistenza di una chiave. Cosa succede se la chiave esiste ma il valore è effettivamente undefined?

var obj = { key: undefined };
obj["key"] !== undefined // false, but the key exists!

Dovresti invece usare l' inoperatore:

"key" in obj // true, regardless of the actual value

Se vuoi verificare se una chiave non esiste, ricorda di usare la parentesi:

!("key" in obj) // true if "key" doesn't exist in object
!"key" in obj   // ERROR!  Equivalent to "false in obj"

Oppure, se si desidera verificare in particolare le proprietà dell'istanza dell'oggetto (e non le proprietà ereditate), utilizzare hasOwnProperty:

obj.hasOwnProperty("key") // true

Per il confronto di prestazioni tra i metodi che sono in, hasOwnPropertye la chiave è undefined, vedere questo benchmark


83
Avere una proprietà con un valore definito manualmente non definito non ha assolutamente senso. Sarebbe davvero un ossimoro.
joebert,

259
Sono convinto che ci sono casi d'uso per avere proprietà intenzionalmente impostate su indefinite.
Ates Goral,

168
Caso d'uso valido: Gecko 1.9.1 [Firefox 3.5] non ha proprietà window.onhashchange. Gecko 1.9.2 [Firefox 3.6] ha impostato questa proprietà su indefinita (fino a quando l'hash non viene modificato). Per rilevare la cronologia hash o la versione del browser, è necessario utilizzare window.hasOwnProperty ("onhashchange");
SamGoody,

7
Un problema simile esiste in PHP dove null == inesistente: stackoverflow.com/q/418066/372654 e, sfortunatamente, anche null ha un uso lì.
Halil Özgür

80
@joebert Solo perché qualcosa non ha senso non significa che non lo incontrerai nel codice di produzione. Ci sono molte biblioteche che fanno cose insensate.
Crashworks,

298

risposta rapida

Come posso verificare se esiste una chiave particolare in un oggetto o in una matrice JavaScript? Se una chiave non esiste e provo ad accedervi, restituirà false? O lanciare un errore?

L'accesso diretto a una proprietà mancante utilizzando lo stile dell'array (associativo) o lo stile dell'oggetto restituirà una costante indefinita .

Il metodo lento e affidabile per operatore e hasOwnProperty

Come le persone hanno già menzionato qui, potresti avere un oggetto con una proprietà associata a una costante "non definita".

 var bizzareObj = {valid_key:  undefined};

In questo caso, si dovrà utilizzare hasOwnProperty o in all'operatore di sapere se la chiave è davvero lì. Ma a quale prezzo?

quindi ti dico ...

in operator e hasOwnProperty sono "metodi" che usano il meccanismo del descrittore di proprietà in Javascript (simile alla riflessione Java nel linguaggio Java).

http://www.ecma-international.org/ecma-262/5.1/#sec-8.10

Il tipo di descrittore di proprietà viene utilizzato per spiegare la manipolazione e la reificazione degli attributi delle proprietà denominate. I valori del tipo Descrittore proprietà sono record composti da campi denominati in cui il nome di ciascun campo è un nome di attributo e il suo valore è un valore di attributo corrispondente come specificato in 8.6.1. Inoltre, qualsiasi campo può essere presente o assente.

D'altra parte, la chiamata di un metodo o chiave oggetto utilizzerà il meccanismo Javascript [[Get]]. È molto più veloce!

prova delle prestazioni

http://jsperf.com/checking-if-a-key-exists-in-a-javascript-array

Confronto dell'accesso chiave in JS.

Utilizzando in operatore
var result = "Impression" in array;

Il risultato è stato

12,931,832 ±0.21% ops/sec      92% slower 
Utilizzo di hasOwnProperty
var result = array.hasOwnProperty("Impression")

Il risultato è stato

16,021,758 ±0.45% ops/sec     91% slower
Accesso diretto agli elementi (stile parentesi)
var result = array["Impression"] === undefined

Il risultato è stato

168,270,439 ±0.13 ops/sec     0.02% slower 
Accesso diretto agli elementi (stile oggetto)
var result = array.Impression  === undefined;

Il risultato è stato

168,303,172 ±0.20%     fastest

EDIT: Qual è il motivo per assegnare a una proprietà il undefinedvalore?

Questa domanda mi confonde. In Javascript, ci sono almeno due riferimenti per oggetti assenti per evitare problemi come questo: nulle undefined.

nullè il valore primitivo che rappresenta l'assenza intenzionale di qualsiasi valore di oggetto, o in breve, la mancanza di valore confermata . D'altra parte, undefinedè un valore sconosciuto (non definito). Se è presente una proprietà che verrà utilizzata in seguito con un valore corretto , prendere in considerazione l'uso di nullriferimento anziché undefinedperché nel momento iniziale la proprietà viene confermata priva di valore.

Confrontare:

var a = {1: null}; 
console.log(a[1] === undefined); // output: false. I know the value at position 1 of a[] is absent and this was by design, i.e.:  the value is defined. 
console.log(a[0] === undefined); // output: true. I cannot say anything about a[0] value. In this case, the key 0 was not in a[].

Consigliare

Evita oggetti con undefinedvalori. Controllare direttamente quando possibile e utilizzare nullper inizializzare i valori delle proprietà. In caso contrario, utilizzare l' inoperatore o il hasOwnProperty()metodo lento .

MODIFICA: 12/04/2018 - NON RILEVANTE PIÙ

Come le persone hanno commentato, le versioni moderne dei motori Javascript (con l'eccezione di Firefox) hanno cambiato l'approccio per le proprietà di accesso. L'implementazione attuale è più lenta della precedente per questo caso particolare, ma la differenza tra chiave di accesso e oggetto è trascurabile.


1
Tutti questi metodi sono accettabili in tutti i browser di uso comune, ad esempio IE8 +?
Giustino,

11
+1 per il benchmarking. Grazie, questa è esattamente l'informazione che speravo di trovare. Sicuramente un argomento forte per scrivere codice che non assegna o si aspetta mai che una chiave contenga un valore indefinito .
TJ Compton

Ero curioso di come ha confrontato Underscore.js (), quindi l'ho aggiunto a jsperf ( versione 11 ). Si scopre che è nel gruppo lento insieme a in e hasOwnProperty ().
mpoisot,

3
Uno dei motivi per cui definirei un valore di hash non definito è che in realtà volevo eliminare quella chiave di proprietà dall'hash, ma delete hash[key]è molto più lento di hash[key] = undefined . Ovviamente in questo caso non ha senso che io abbia bisogno indell'operatore, ma funge da controesempio a "dovremmo sempre evitare di impostare il valore su indefinito".
Alan Tam,

1
Come menzionato da @ HüseyinYağlı, se si controlla il collegamento jsperf , le prestazioni sono cambiate in modo significativo tra i diversi metodi per la maggior parte dei browser da quando questa risposta è stata originariamente scritta. Firefox è uno dei pochi che presenta ancora un vantaggio significativo utilizzando i metodi array o object, ma per molti altri browser le differenze sono trascurabili.
kevinmicke,

144

Tornerà undefined.

var aa = {hello: "world"};
alert( aa["hello"] );      // popup box with "world"
alert( aa["goodbye"] );    // popup box with "undefined"

undefinedè un valore costante speciale. Quindi puoi dire, ad es

// note the three equal signs so that null won't be equal to undefined
if( aa["goodbye"] === undefined ) {
    // do something
}

Questo è probabilmente il modo migliore per verificare la presenza di chiavi mancanti. Tuttavia, come indicato in un commento di seguito, è teoricamente possibile che si desideri avere il valore effettivo undefined. Non ho mai avuto bisogno di farlo e non riesco a pensare a una ragione per cui non avrei mai voluto, ma solo per completezza, puoi usare l' inoperatore

// this works even if you have {"goodbye": undefined}
if( "goodbye" in aa ) {
    // do something
}

8
Cosa succede se la chiave esiste ma il valore non è effettivamente definito?
Ates Goral,

13
Dovresti usare === invece di == quando paragonato a indefinito, altrimenti null comparerà uguale a indefinito.
Matthew Crumley,

10
Eli la tua risposta non è completamente precisa. Perché comunque (e ovviamente questo non dovrebbe mai essere fatto) indefinito non è un valore costante speciale. In realtà, non è una parola chiave riservata e puoi sovrascriverla, diciamo ad esempio quella var undefined = 42;. Quando si esegue il test per oggetti di scena non definiti, è necessario utilizzare sempre ((typeof variable) === "undefined").
ssice,

1
@ssice undefinednon è una proprietà scrivibile in base alle specifiche ecma-international.org/ecma-262/5.1/#sec-15.1.1.3
therealrootuser

1
Nelle versioni precedenti di JavaScript, 'undefined' e 'NaN' erano variabili mutabili che potevano essere ridefinite o assegnate ad altri valori . Questa è stata una brutta cosa. È stato corretto in ECMAScript 5.
jkdev il


29
"key" in obj

Probabilmente sta testando solo i valori degli attributi degli oggetti che sono molto diversi dalle chiavi dell'array


Questo codice sarà valido anche per una chiave definita sul prototipo della classe: funzione A () {}; A.prototype.b = 2; var a = new A (); Quindi 'b' in a è vero. Mentre a.hasOwnProperty ('b') è ovviamente falso.
Alexander,

24

Tre modi per verificare se una proprietà è presente in un oggetto JavaScript:

  1. !!obj.theProperty
    Converte il valore in bool. ritorna trueper tutti tranne il falsevalore
  2. ' theProperty' in obj
    Restituirà vero se la proprietà esiste, indipendentemente dal suo valore (anche vuoto)
  3. obj.hasOwnProperty('theProperty')
    Non controlla la catena del prototipo. (poiché tutti gli oggetti hanno il toStringmetodo, 1 e 2 restituiranno true su di esso, mentre 3 possono restituire false su di esso.)

Riferimento:

http://book.mixu.net/node/ch5.html


!! obj.theProperty fallisce quando il valore non è definito. Es:var a = {a : undefined, b : null}; !!a.a **will return false**
ARJUN,

dalla recensione: !!obj.thePropertynon è una soluzione per verificare se un oggetto ha una proprietà denominata theProperty. Fallisce per qualsiasi valore di proprietà falsey, undefined, null, numerico 0o NaN, e la stringa vuota""
traktor53

15

Se si utilizza la libreria underscore.js, le operazioni oggetto / matrice diventano semplici.

Nel tuo caso è possibile utilizzare il metodo _.has. Esempio:

yourArray = {age: "10"}

_.has(yourArray, "age")

ritorna vero

Ma,

_.has(yourArray, "invalidKey")

restituisce false


15

Risposta:

if ("key" in myObj)
{
    console.log("key exists!");
}
else
{
    console.log("key doesn't exist!");
}

Spiegazione:

L' inoperatore verificherà se la chiave esiste nell'oggetto. Se hai verificato se il valore non era definito:, if (myObj["key"] === 'undefined')potresti incorrere in problemi perché potrebbe esistere una chiave nel tuo oggetto con il undefinedvalore.

Per questa ragione, è molto meglio usare prima l' inoperatore e poi confrontare il valore che si trova all'interno della chiave una volta che si sa già che esiste.


12

Ecco una funzione di aiuto che trovo abbastanza utile

Questo keyExists(key, search)può essere usato per cercare facilmente una chiave all'interno di oggetti o matrici!

Basta passarlo la chiave che si desidera trovare e cercare obj (l'oggetto o l'array) in cui si desidera trovarlo.

function keyExists(key, search) {
        if (!search || (search.constructor !== Array && search.constructor !== Object)) {
            return false;
        }
        for (var i = 0; i < search.length; i++) {
            if (search[i] === key) {
                return true;
            }
        }
        return key in search;
    }

// How to use it:
// Searching for keys in Arrays
console.log(keyExists('apple', ['apple', 'banana', 'orange'])); // true
console.log(keyExists('fruit', ['apple', 'banana', 'orange'])); // false

// Searching for keys in Objects
console.log(keyExists('age', {'name': 'Bill', 'age': 29 })); // true
console.log(keyExists('title', {'name': 'Jason', 'age': 29 })); // false

È stato abbastanza affidabile e funziona bene su più browser.


6
Questo sembra un po 'confuso: in primo luogo, quando si cerca un array, questo metodo controlla un valore , non una chiave. In secondo luogo, perché scorrere attraverso un array come questo quando è possibile utilizzare il Array.indexOfmetodo integrato ? (se stai cercando un valore, cioè)
Nick F,

9

vanila js

yourObjName.hasOwnProperty(key) : true ? false;

Se si desidera verificare se l'oggetto ha almeno una proprietà in es2015

Object.keys(yourObjName).length : true ? false

7

Soluzione ES6

usando Array#somee Object.keys. Restituirà vero se la chiave data esiste nell'oggetto o falso in caso contrario.

var obj = {foo: 'one', bar: 'two'};
    
function isKeyInObject(obj, key) {
    var res = Object.keys(obj).some(v => v == key);
    console.log(res);
}

isKeyInObject(obj, 'foo');
isKeyInObject(obj, 'something');

Esempio di una riga.

console.log(Object.keys({foo: 'one', bar: 'two'}).some(v => v == 'foo'));


1
Non riuscirà per le proprietà non numerabili dell'oggetto.
Sid

@Sid Fammi un esempio.
gentile utente

Ecco qui. let joshua = {nome: 'Joshua', indirizzo: 'London'}; Object.defineProperty (joshua, 'isMarried', {valore: vero, enumerabile: falso}); console.log ('isMarried' in Object.keys (joshua))
Sid

Sto applicando la tua soluzione sul mio oggetto. Non dovrebbe essere vero per la prima uscita? console.log (Object.keys (joshua) .some (v => v == 'isMarried')); console.log (joshua.isMarried);
Sid

1
Mi dispiace ma hai controllato l'output della seconda istruzione della console? Object.defineProperty equivale a impostare la proprietà usando la notazione punto.
Sid

6

Possiamo usare - hasOwnProperty.call(obj, key);

Il modo underscore.js -

if(_.has(this.options, 'login')){
  //key 'login' exists in this.options 
}

_.has = function(obj, key) {
  return hasOwnProperty.call(obj, key);
};

5

Il modo più semplice per verificare è

"key" in object

per esempio:

var obj = {
  a: 1,
  b: 2,
}
"a" in obj // true
"c" in obj // false

Il valore restituito come vero implica che la chiave esiste nell'oggetto.


4

Per quelli che hanno lodashincluso nel loro progetto:
esiste un metodo lodash _.get che cerca di ottenere chiavi "profonde":

Ottiene il valore sul percorso dell'oggetto. Se il valore risolto non è definito, il valore predefinito viene restituito al suo posto.

var object = { 'a': [{ 'b': { 'c': 3 } }] };

console.log(
  _.get(object, 'a[0].b.c'),           // => 3
  _.get(object, ['a', '0', 'b', 'c']), // => 3
  _.get(object, 'a.b.c'),              // => undefined 
  _.get(object, 'a.b.c', 'default')    // => 'default'
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


Questo verificherà efficacemente se tale chiave, per quanto profonda , è definita e non genererà un errore che potrebbe danneggiare il flusso del programma se tale chiave non è definita.


4

Sebbene ciò non controlli necessariamente l'esistenza di una chiave, verifica la veridicità di un valore. Che undefinede nullcadono sotto.

Boolean(obj.foo)

Questa soluzione funziona meglio per me perché uso il dattiloscritto e l'uso di stringhe in questo modo 'foo' in objo obj.hasOwnProperty('foo') per verificare se esiste una chiave o meno non mi fornisce intellisense.


3

Se si desidera verificare la presenza di una chiave a qualsiasi profondità su un oggetto e tenere conto dei valori di falsità, considerare questa riga per una funzione di utilità:

var keyExistsOn = (o, k) => k.split(".").reduce((a, c) => a.hasOwnProperty(c) ? a[c] || 1 : false, Object.assign({}, o)) === false ? false : true;

risultati

var obj = {
    test: "",
    locals: {
        test: "",
        test2: false,
        test3: NaN,
        test4: 0,
        test5: undefined,
        auth: {
            user: "hw"
        }
    }
}

keyExistsOn(obj, "")
> false
keyExistsOn(obj, "locals.test")
> true
keyExistsOn(obj, "locals.test2")
> true
keyExistsOn(obj, "locals.test3")
> true
keyExistsOn(obj, "locals.test4")
> true
keyExistsOn(obj, "locals.test5")
> true
keyExistsOn(obj, "sdsdf")
false
keyExistsOn(obj, "sdsdf.rtsd")
false
keyExistsOn(obj, "sdsdf.234d")
false
keyExistsOn(obj, "2134.sdsdf.234d")
false
keyExistsOn(obj, "locals")
true
keyExistsOn(obj, "locals.")
false
keyExistsOn(obj, "locals.auth")
true
keyExistsOn(obj, "locals.autht")
false
keyExistsOn(obj, "locals.auth.")
false
keyExistsOn(obj, "locals.auth.user")
true
keyExistsOn(obj, "locals.auth.userr")
false
keyExistsOn(obj, "locals.auth.user.")
false
keyExistsOn(obj, "locals.auth.user")
true

Vedi anche questo pacchetto NPM: https://www.npmjs.com/package/has-deep-value


3
const object1 = {
  a: 'something',
  b: 'something',
  c: 'something'
};

const key = 's';

// Object.keys(object1) will return array of the object keys ['a', 'b', 'c']

Object.keys(object1).indexOf(key) === -1 ? 'the key is not there' : 'yep the key is exist';

3

Nel mondo "array" possiamo considerare gli indici come una sorta di chiave. Ciò che sorprende l' inoperatore (che è una buona scelta per l'oggetto) funziona anche con le matrici. Il valore restituito per la chiave inesistente èundefined

let arr = ["a","b","c"]; // we have indexes: 0,1,2
delete arr[1];           // set 'empty' at index 1
arr.pop();               // remove last item

console.log(0 in arr,  arr[0]);
console.log(1 in arr,  arr[1]);
console.log(2 in arr,  arr[2]);


2

yourArray.indexOf (yourArrayKeyName)> -1

fruit = ['apple', 'grapes', 'banana']

fruit.indexOf('apple') > -1

vero


fruit = ['apple', 'grapes', 'banana']

fruit.indexOf('apple1') > -1

falso


0

Questo esempio può dimostrare le differenze tra i diversi modi. Spero che ti possa aiutare a scegliere quello giusto per le tue esigenze:

// Lets create object `a` using create function `A`
function A(){};
A.prototype.onProtDef=2;
A.prototype.onProtUndef=undefined;
var a=new A();
a.ownProp = 3;
a.ownPropUndef = undefined;

// Let's try different methods:

a.onProtDef; // 2
a.onProtUndef; // undefined
a.ownProp; // 3
a.ownPropUndef; // undefined
a.whatEver; // undefined
a.valueOf; // ƒ valueOf() { [native code] }

a.hasOwnProperty('onProtDef'); // false
a.hasOwnProperty('onProtUndef'); // false
a.hasOwnProperty('ownProp'); // true
a.hasOwnProperty('ownPropUndef'); // true
a.hasOwnProperty('whatEver'); // false
a.hasOwnProperty('valueOf'); // false

'onProtDef' in a; // true
'onProtUndef' in a; // true
'ownProp' in a; // true
'ownPropUndef' in a; // true
'whatEver' in a; // false
'valueOf' in a; // true (on the prototype chain - Object.valueOf)

Object.keys(a); // ["ownProp", "ownPropUndef"]

-1

Nuova fantastica soluzione con JavaScript Destructuring :

let obj = {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3",
};

let {key1, key2, key3, key4} = obj;

// key1 = "value1"
// key2 = "value2"
// key3 = "value3"
// key4 = undefined

// Can easily use `if` here on key4
if(!key4) { console.log("key not present"); } // Key not present

Controlla altri usi di JavaScript Destructuring

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.