Vérifier si une clé existe dans un objet JavaScript?

2973

Comment vérifier si une clé particulière existe dans un objet ou un tableau JavaScript?

Si une clé n'existe pas et que j'essaie d'y accéder, est-ce qu'elle retournera false? Ou lancer une erreur?

Adam Ernst
la source
2
Tout (presque tout) en JavaScript est un objet ou peut être converti en un seul. C'est là que naissent des pseudo-tableaux associatifs, comme l'a souligné @PatrickM.
Andrew Larsson
ce benchmark jsben.ch/#/WqlIl vous donne un aperçu des moyens les plus courants pour réaliser ce contrôle.
EscapeNetscape
une solution rapide, généralement je property.key = property.key || 'some default value'
choisis

Réponses:

4121

La vérification de l'indéfini-ness n'est pas un moyen précis de tester si une clé existe. Et si la clé existe mais que la valeur est réellement undefined?

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

Vous devez plutôt utiliser l' inopérateur:

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

Si vous souhaitez vérifier si une clé n'existe pas, n'oubliez pas d'utiliser des parenthèses:

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

Ou, si vous souhaitez tester en particulier les propriétés de l'instance d'objet (et non les propriétés héritées), utilisez hasOwnProperty:

obj.hasOwnProperty("key") // true

A titre de comparaison des performances entre les méthodes qui sont in, hasOwnPropertyet est la clé undefined, voir cette référence

Ates Goral
la source
83
Avoir une propriété avec une valeur non définie définie manuellement n'a absolument aucun sens. Ce serait vraiment un oxymore.
joebert
259
Je suis convaincu qu'il existe des cas d'utilisation pour lesquels les propriétés sont intentionnellement définies sur undefined.
Ates Goral
168
Cas d'utilisation valide: Gecko 1.9.1 [Firefox 3.5] n'a pas de propriété window.onhashchange. Gecko 1.9.2 [Firefox 3.6] a cette propriété définie sur undefined (jusqu'à ce que le hachage change). Pour pouvoir détecter l'historique de hachage ou la version du navigateur, il faut utiliser window.hasOwnProperty ("onhashchange");
SamGoody
7
Un problème similaire existe en PHP où null == inexistant: stackoverflow.com/q/418066/372654 et malheureusement, null y est également utilisé.
Halil Özgür
80
@joebert Ce n'est pas parce que quelque chose n'a pas de sens que vous ne le rencontrerez pas dans le code de production. Il existe de nombreuses bibliothèques qui font des choses absurdes.
Crashworks
298

réponse rapide

Comment vérifier si une clé particulière existe dans un objet ou un tableau JavaScript? Si une clé n'existe pas et que j'essaie d'y accéder, est-ce qu'elle retournera false? Ou lancer une erreur?

L'accès direct à une propriété manquante à l'aide d'un style de tableau (associatif) ou d'un style d'objet renvoie une constante non définie .

La lente et fiable dans l' opérateur et hasOwnProperty méthode

Comme les gens l'ont déjà mentionné ici, vous pourriez avoir un objet avec une propriété associée à une constante "non définie".

 var bizzareObj = {valid_key:  undefined};

Dans ce cas, vous devrez utiliser hasOwnProperty ou in operator pour savoir si la clé est vraiment là. Mais à quel prix?

alors je vous le dis ...

in operator et hasOwnProperty sont des "méthodes" qui utilisent le mécanisme Property Descriptor en Javascript (similaire à la réflexion Java dans le langage Java).

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

Le type Descripteur de propriété est utilisé pour expliquer la manipulation et la réification des attributs de propriété nommés. Les valeurs du type Descripteur de propriété sont des enregistrements composés de champs nommés où le nom de chaque champ est un nom d'attribut et sa valeur est une valeur d'attribut correspondante comme spécifié en 8.6.1. De plus, tout champ peut être présent ou absent.

D'un autre côté, l'appel d'une méthode ou d'une clé d'objet utilisera le mécanisme Javascript [[Get]]. C'est beaucoup plus rapide!

référence

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

Comparaison de l'accès aux clés dans JS.

Utilisation dans l' opérateur
var result = "Impression" in array;

Le résultat fut

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

Le résultat fut

16,021,758 ±0.45% ops/sec     91% slower
Accès direct aux éléments (style crochets)
var result = array["Impression"] === undefined

Le résultat fut

168,270,439 ±0.13 ops/sec     0.02% slower 
Accès direct aux éléments (style d'objet)
var result = array.Impression  === undefined;

Le résultat fut

168,303,172 ±0.20%     fastest

EDIT: Quelle est la raison pour attribuer à une propriété la undefinedvaleur?

Cette question me laisse perplexe. En Javascript, il existe au moins deux références pour les objets absents afin d'éviter des problèmes comme celui-ci: nullet undefined.

nullest la valeur primitive qui représente l'absence intentionnelle de toute valeur d'objet, ou en bref, le manque de valeur confirmé . En revanche, undefinedest une valeur inconnue (non définie). S'il existe une propriété qui sera utilisée plus tard avec une valeur appropriée , considérez l'utilisation d'une nullréférence au lieu de undefinedparce qu'au moment initial, il est confirmé que la propriété n'a pas de valeur.

Comparer:

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[].

Conseiller

Évitez les objets avec des undefinedvaleurs. Vérifiez directement dans la mesure du possible et utilisez nullpour initialiser les valeurs des propriétés. Sinon, utilisez l' inopérateur ou la hasOwnProperty()méthode lente .

EDIT: 12/04/2018 - PLUS PERTINENT

Comme les gens l'ont commenté, les versions modernes des moteurs Javascript (à l'exception de Firefox) ont changé l'approche pour les propriétés d'accès. L'implémentation actuelle est plus lente que la précédente pour ce cas particulier, mais la différence entre la clé d'accès et l'objet est négligeable.

rdllopes
la source
1
Toutes ces méthodes sont-elles acceptables dans tous les navigateurs couramment utilisés, par exemple IE8 +?
Justin
11
+1 pour l'analyse comparative. Merci, c'est exactement l'information que j'espérais trouver. Certainement un argument fort pour écrire du code qui n'attribue ou ne s'attend jamais à ce qu'une clé contienne la valeur non définie .
TJ Compton
J'étais curieux de voir comment Underscore.js a () comparé, alors je l'ai ajouté au jsperf ( version 11 ). Il s'avère que c'est dans le groupe lent avec in et hasOwnProperty ().
mpoisot
3
L'une des raisons pour lesquelles je définirais undefined à une valeur de hachage est que je voulais réellement supprimer cette clé de propriété du hachage, mais delete hash[key]est beaucoup plus lent que hash[key] = undefined . Bien sûr, dans ce cas, cela n'a aucun sens pour moi d'avoir besoin de l' inopérateur, mais cela agit comme un contre-exemple de «nous devons toujours éviter de définir la valeur sur undefined».
Alan Tam
1
Comme @ HüseyinYağlı l'a mentionné, si vous vérifiez le lien jsperf , les performances ont considérablement changé entre les différentes méthodes pour la plupart des navigateurs depuis que cette réponse a été écrite à l'origine. Firefox est l'un des rares qui a encore un avantage significatif en utilisant les méthodes tableau ou objet, mais pour de nombreux autres navigateurs, les différences sont négligeables.
kevinmicke
144

Il reviendra undefined.

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

undefinedest une valeur constante spéciale. Vous pouvez donc dire, par exemple

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

C'est probablement le meilleur moyen de vérifier les clés manquantes. Cependant, comme indiqué dans un commentaire ci-dessous, il est théoriquement possible que vous souhaitiez que la valeur réelle soit undefined. Je n'ai jamais eu besoin de faire cela et je ne peux pas penser à une raison pour laquelle je le souhaiterais, mais juste pour être complet, vous pouvez utiliser l' inopérateur

// this works even if you have {"goodbye": undefined}
if( "goodbye" in aa ) {
    // do something
}
Eli Courtwright
la source
8
Que faire si la clé existe mais que la valeur n'est en fait pas définie?
Ates Goral
13
Vous devez utiliser === au lieu de == lors de la comparaison avec undefined, sinon null sera égal à undefined.
Matthew Crumley
10
Eli, votre réponse n'est pas complètement exacte. Parce que de toute façon (et bien sûr cela ne devrait jamais être fait) undefined n'est pas une valeur constante spéciale. En fait, ce n'est pas un mot-clé réservé et vous pouvez l'écraser, disons par exemple ça var undefined = 42;. Lorsque vous testez des accessoires non définis, vous devez toujours les utiliser ((typeof variable) === "undefined").
2011
1
@ssice undefinedn'est pas une propriété accessible en écriture selon la spécification ecma-international.org/ecma-262/5.1/#sec-15.1.1.3
therealrootuser
1
Dans les versions antérieures de JavaScript, «undefined» et «NaN» étaient des variables modifiables qui pouvaient être redéfinies ou attribuées à d'autres valeurs . C'était une mauvaise chose. Il a été corrigé dans ECMAScript 5.
jkdev
29
"key" in obj

Teste probablement uniquement des valeurs d'attribut d'objet très différentes des clés de tableau

user2320522
la source
Ce code donnera aussi vrai pour une clé qui est définie sur le prototype de classe: fonction A () {}; A.prototype.b = 2; var a = new A (); Alors «b» dans a est vrai. Alors que a.hasOwnProperty ('b') est bien sûr faux.
Alexander
24

Trois façons de vérifier si une propriété est présente dans un objet javascript:

  1. !!obj.theProperty
    Convertira la valeur en bool. renvoie truepour tout sauf la falsevaleur
  2. ' theProperty' dans obj
    Renvoie true si la propriété existe, quelle que soit sa valeur (même vide)
  3. obj.hasOwnProperty('theProperty')
    Ne vérifie pas la chaîne prototype. (puisque tous les objets ont la toStringméthode, 1 et 2 retourneront true dessus, tandis que 3 peut retourner false dessus.)

Référence:

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

Lavi Avigdor
la source
!! obj.theProperty échoue lorsque la valeur n'est pas définie. Ex:var a = {a : undefined, b : null}; !!a.a **will return false**
ARJUN
from review: !!obj.thePropertyn'est pas une solution pour vérifier si un objet a une propriété nommée theProperty. Il échoue pour toute valeur de propriété falsey undefined, null, numérique 0ou NaN, et la chaîne vide""
traktor53
15

Si vous utilisez la bibliothèque underscore.js , les opérations objet / tableau deviennent simples.

Dans votre cas, la méthode _.has peut être utilisée. Exemple:

yourArray = {age: "10"}

_.has(yourArray, "age")

renvoie vrai

Mais,

_.has(yourArray, "invalidKey")

renvoie faux

vatsal
la source
15

Réponse:

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

Explication:

L' inopérateur vérifiera si la clé existe dans l'objet. Si vous avez vérifié si la valeur n'était pas définie:, if (myObj["key"] === 'undefined')vous pourriez rencontrer des problèmes car une clé pourrait éventuellement exister dans votre objet avec la undefinedvaleur.

Pour cette raison, il est bien préférable d'utiliser d'abord l' inopérateur, puis de comparer la valeur qui se trouve à l'intérieur de la clé une fois que vous savez déjà qu'elle existe.

Webeng
la source
12

Voici une fonction d'aide que je trouve très utile

Cela keyExists(key, search)peut être utilisé pour rechercher facilement une clé dans des objets ou des tableaux!

Passez-lui simplement la clé que vous souhaitez rechercher et recherchez obj (l'objet ou le tableau) dans lequel vous souhaitez le trouver.

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

Il a été assez fiable et fonctionne bien entre les navigateurs.

jaredwilli
la source
6
Cela semble un peu confus: tout d'abord, lors de la recherche d'un tableau, cette méthode vérifie une valeur , pas une clé. Deuxièmement, pourquoi parcourir un tableau comme celui-ci lorsque vous pouvez utiliser la Array.indexOfméthode intégrée ? (si vous cherchez une valeur, c'est)
Nick F
9

vanila js

yourObjName.hasOwnProperty(key) : true ? false;

Si vous souhaitez vérifier si l'objet possède au moins une propriété dans es2015

Object.keys(yourObjName).length : true ? false
Hajji Tarik
la source
7

Solution ES6

en utilisant Array#someet Object.keys. Il renverra true si une clé donnée existe dans l'objet ou false dans le cas contraire.

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');

Exemple d'une ligne.

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

gentil utilisateur
la source
1
Il échouera pour les propriétés non numérotables de l'objet.
Sid
@Sid Donnez-moi un exemple.
gentil utilisateur
Voici. let joshua = {nom: 'Joshua', adresse: 'Londres'}; Object.defineProperty (joshua, 'isMarried', {valeur: vrai, énumérable: faux}); console.log ('isMarried' dans Object.keys (joshua))
Sid
J'applique votre solution sur mon objet. Cela ne devrait-il pas être vrai pour la première sortie? console.log (Object.keys (joshua) .some (v => v == 'isMarried')); console.log (joshua.isMarried);
Sid
1
Je suis désolé, mais avez-vous vérifié la sortie de la deuxième déclaration de la console? Object.defineProperty équivaut à définir la propriété à l'aide de la notation par points.
Sid
6

On peut utiliser - hasOwnProperty.call(obj, key);

La manière underscore.js -

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

_.has = function(obj, key) {
  return hasOwnProperty.call(obj, key);
};
Mohan Dere
la source
5

La façon la plus simple de vérifier est

"key" in object

par exemple:

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

La valeur de retour true indique que la clé existe dans l'objet.

shekhardtu
la source
4

Pour ceux qui ont lodashinclus dans leur projet:
Il existe une méthode lodash _.get qui essaie d'obtenir des clés "profondes":

Obtient la valeur au chemin de l'objet. Si la valeur résolue n'est pas définie, la valeur par défaut est retournée à sa place.

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>


Cela vérifiera efficacement si cette clé, quelle que soit sa profondeur , est définie et ne générera pas d'erreur qui pourrait nuire au flux de votre programme si cette clé n'est pas définie.

vsync
la source
4

Bien que cela ne vérifie pas nécessairement si une clé existe, il vérifie la véracité d'une valeur. Qui undefinedet nulltomber sous.

Boolean(obj.foo)

Cette solution me convient le mieux, car j'utilise du texte dactylographié, et l'utilisation de chaînes de ce type 'foo' in objou obj.hasOwnProperty('foo')pour vérifier si une clé existe ou non ne me fournit pas d'intellisense.

realappie
la source
3

Si vous voulez vérifier n'importe quelle clé à n'importe quelle profondeur sur un objet et tenir compte des valeurs de falsey, considérez cette ligne pour une fonction d'utilité:

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

Résultats

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

Voir également ce package NPM: https://www.npmjs.com/package/has-deep-value

Alex
la source
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';
Sarea
la source
3

Dans le monde des tableaux, nous pouvons considérer les index comme une sorte de clé. Ce qui est surprenant, l' inopérateur (qui est un bon choix pour l'objet) fonctionne également avec les tableaux. La valeur renvoyée pour la clé non existante estundefined

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]);

Kamil Kiełczewski
la source
2

yourArray.indexOf (yourArrayKeyName)> -1

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

fruit.indexOf('apple') > -1

vrai


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

fruit.indexOf('apple1') > -1

faux

Anupam Maurya
la source
0

Ces exemples peuvent montrer les différences entre les différentes manières. J'espère que cela vous aidera à choisir celui qui convient à vos besoins:

// 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"]
Alexandre
la source
-1

Nouvelle solution impressionnante avec la déstructuration JavaScript :

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

Vérifiez les autres utilisations de JavaScript Destructuring

NAVIN
la source