Überprüfen, ob ein Schlüssel in einem JavaScript-Objekt vorhanden ist?

2969

Wie überprüfe ich, ob ein bestimmter Schlüssel in einem JavaScript-Objekt oder -Array vorhanden ist?

Wenn ein Schlüssel nicht vorhanden ist und ich versuche, darauf zuzugreifen, wird er dann false zurückgeben? Oder einen Fehler werfen?

Adam Ernst
quelle
2
Alles (fast alles) in JavaScript ist ein Objekt oder kann als eines gegossen werden. Hier werden pseudoassoziative Arrays geboren, genau wie @PatrickM.
Andrew Larsson
Dieser Benchmark jsben.ch/#/WqlIl gibt Ihnen einen Überblick über die gängigsten Methoden, um diese Prüfung durchzuführen .
EscapeNetscape
Eine schnelle Problemumgehung, für die ich mich normalerweise entscheide property.key = property.key || 'some default value', nur für den Fall, dass dieser Schlüssel mit einem gewissen Wert vorhanden sein soll
RGLSV

Antworten:

4119

Das Überprüfen auf Undefiniertheit ist keine genaue Methode, um zu testen, ob ein Schlüssel vorhanden ist. Was ist, wenn der Schlüssel vorhanden ist, der Wert jedoch tatsächlich undefined?

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

Sie sollten stattdessen den inOperator verwenden:

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

Wenn Sie überprüfen möchten, ob kein Schlüssel vorhanden ist, denken Sie daran, Klammern zu verwenden:

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

Wenn Sie insbesondere auf Eigenschaften der Objektinstanz (und nicht auf geerbte Eigenschaften) testen möchten, verwenden Sie hasOwnProperty:

obj.hasOwnProperty("key") // true

Aus Performance - Vergleich zwischen den Methoden , die sind in, hasOwnPropertyund Schlüssel ist , undefinedfinden Sie in diesem Benchmark

Ates Goral
quelle
83
Eine Eigenschaft mit einem manuell definierten Wert von undefined zu haben, macht absolut keinen Sinn. Es wäre wirklich ein Oxymoron.
Joebert
259
Ich bin überzeugt, dass es Anwendungsfälle gibt, bei denen Eigenschaften absichtlich auf undefiniert gesetzt werden.
Ates Goral
168
Gültiger Anwendungsfall: Gecko 1.9.1 [Firefox 3.5] hat keine window.onhashchange-Eigenschaft. Bei Gecko 1.9.2 [Firefox 3.6] ist diese Eigenschaft auf undefiniert gesetzt (bis sich der Hash ändert). Um den Hash-Verlauf oder die Browserversion zu erkennen, muss window.hasOwnProperty ("onhashchange") verwendet werden.
SamGoody
7
Ein ähnliches Problem besteht in PHP, wo null == nicht vorhanden ist: stackoverflow.com/q/418066/372654 und leider hat null auch dort eine Verwendung.
Halil Özgür
80
@joebert Nur weil etwas Unsinn ist, heißt das nicht, dass Sie es im Produktionscode nicht finden werden. Es gibt viele Bibliotheken, die unsinnige Dinge tun.
Crashworks
298

schnelle Antwort

Wie überprüfe ich, ob ein bestimmter Schlüssel in einem JavaScript-Objekt oder -Array vorhanden ist? Wenn ein Schlüssel nicht vorhanden ist und ich versuche, darauf zuzugreifen, wird er dann false zurückgeben? Oder einen Fehler werfen?

Wenn Sie direkt auf eine fehlende Eigenschaft mit einem (assoziativen) Array- oder Objektstil zugreifen, wird eine undefinierte Konstante zurückgegeben.

Der langsame und zuverlässig in Operator und hasOwnProperty Verfahren

Wie bereits erwähnt, können Sie ein Objekt mit einer Eigenschaft haben, die einer "undefinierten" Konstante zugeordnet ist.

 var bizzareObj = {valid_key:  undefined};

In diesem Fall müssen Sie hasOwnProperty oder in operator verwenden , um festzustellen , ob der Schlüssel wirklich vorhanden ist. Aber zu welchem ​​Preis?

Also, ich sage dir ...

in operator und hasOwnProperty sind "Methoden", die den Property Descriptor-Mechanismus in Javascript verwenden (ähnlich der Java-Reflektion in der Java-Sprache).

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

Der Property Descriptor-Typ wird verwendet, um die Manipulation und Reifizierung benannter Eigenschaftsattribute zu erläutern. Werte vom Typ Property Descriptor sind Datensätze, die aus benannten Feldern bestehen, wobei der Name jedes Felds ein Attributname und sein Wert ein entsprechender Attributwert ist, wie in 8.6.1 angegeben. Außerdem kann jedes Feld vorhanden sein oder fehlen.

Auf der anderen Seite wird beim Aufrufen einer Objektmethode oder eines Objektschlüssels der Javascript-Mechanismus [[Get]] verwendet. Das geht viel schneller!

Benchmark

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

Vergleichen des Schlüsselzugriffs in JS.

Verwendung im Operator
var result = "Impression" in array;

Das Ergebnis war

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

Das Ergebnis war

16,021,758 ±0.45% ops/sec     91% slower
Direkter Zugriff auf Elemente (Klammerstil)
var result = array["Impression"] === undefined

Das Ergebnis war

168,270,439 ±0.13 ops/sec     0.02% slower 
Direkter Zugriff auf Elemente (Objektstil)
var result = array.Impression  === undefined;

Das Ergebnis war

168,303,172 ±0.20%     fastest

EDIT: Was ist der Grund, einer Eigenschaft den undefinedWert zuzuweisen ?

Diese Frage verwirrt mich. In Javascript gibt es mindestens zwei Referenzen für fehlende Objekte, um solche Probleme zu vermeiden: nullund undefined.

nullist der primitive Wert, der das absichtliche Fehlen eines Objektwerts oder kurz gesagt den bestätigten Wertmangel darstellt. Andererseits undefinedist ein unbekannter Wert (nicht definiert). Wenn es eine Eigenschaft gibt, die später mit einem geeigneten Wert verwendet wird, ziehen Sie die Verwendung einer nullReferenz undefinedin Betracht, anstatt zu bestätigen , dass der Eigenschaft im ersten Moment ein Wert fehlt.

Vergleichen Sie:

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

Beraten

Vermeiden Sie Objekte mit undefinedWerten. Überprüfen Sie dies nullnach Möglichkeit direkt und verwenden Sie es , um Eigenschaftswerte zu initialisieren. Verwenden Sie andernfalls den langsamen inOperator oder die langsame hasOwnProperty()Methode.

EDIT: 12/04/2018 - NICHT MEHR RELEVANT

Wie bereits erwähnt, haben moderne Versionen der Javascript-Engines (mit Firefox-Ausnahme) den Ansatz für Zugriffseigenschaften geändert. Die aktuelle Implementierung ist in diesem speziellen Fall langsamer als die vorherige, aber der Unterschied zwischen Zugriffsschlüssel und Objekt ist vernachlässigbar.

rdllopes
quelle
1
Sind alle diese Methoden in allen gängigen Browsern akzeptabel, z. B. IE8 +?
Justin
11
+1 für das Benchmarking. Vielen Dank, genau diese Informationen habe ich mir erhofft. Auf jeden Fall ein starkes Argument, um Code zu schreiben, der niemals einen Schlüssel zuweist oder erwartet, der den undefinierten Wert enthält .
TJ Compton
Ich war neugierig, wie Underscore.js () verglichen hat, also habe ich es dem jsperf ( Version 11 ) hinzugefügt . Es stellt sich heraus, dass es zusammen mit in und hasOwnProperty () in der langsamen Gruppe ist.
Mpoisot
3
Ein Grund , warum ich zu einem Hash - Wert eingestellt undefiniert würde , ist , dass ich tatsächlich die Eigenschaft Schlüssel aus dem Hash löschen wollte, aber delete hash[key]ist viel langsamer als hash[key] = undefined . In diesem Fall macht es für mich natürlich keinen Sinn, den inOperator zu benötigen , aber es dient als Gegenbeispiel zu „Wir sollten immer vermeiden, den Wert auf undefiniert zu setzen“.
Alan Tam
1
Wie @ HüseyinYağlı bereits erwähnt hat, hat sich beim Überprüfen des jsperf- Links die Leistung zwischen den verschiedenen Methoden für die meisten Browser erheblich geändert, seit diese Antwort ursprünglich geschrieben wurde. Firefox ist einer der wenigen, der mit den Array- oder Objektmethoden noch einen erheblichen Vorteil hat, aber für viele andere Browser sind die Unterschiede vernachlässigbar.
Kevinmicke
144

Es wird zurückkehren undefined.

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

undefinedist ein spezieller konstanter Wert. Sie können also sagen, z

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

Dies ist wahrscheinlich der beste Weg, um nach fehlenden Schlüsseln zu suchen. Wie in einem Kommentar unten ausgeführt, ist es jedoch theoretisch möglich, dass Sie den tatsächlichen Wert haben möchten undefined. Ich musste das nie tun und kann mir keinen Grund vorstellen, warum ich es jemals wollte, aber der Vollständigkeit halber können Sie den inOperator verwenden

// this works even if you have {"goodbye": undefined}
if( "goodbye" in aa ) {
    // do something
}
Eli Courtwright
quelle
8
Was ist, wenn der Schlüssel vorhanden ist, der Wert jedoch tatsächlich undefiniert ist?
Ates Goral
13
Sie sollten === anstelle von == verwenden, wenn Sie mit undefined vergleichen. Andernfalls wird null gleich undefined verglichen.
Matthew Crumley
10
Eli deine Antwort ist nicht ganz richtig. Denn ohnehin (und das sollte natürlich nie gemacht werden) ist undefined kein spezieller konstanter Wert. Tatsächlich ist es kein reserviertes Schlüsselwort, und Sie können es überschreiben, sagen wir zum Beispiel das var undefined = 42;. Wenn Sie auf undefinierte Requisiten testen, sollten Sie immer verwenden ((typeof variable) === "undefined").
ssice
1
@ssice undefinedist keine beschreibbare Eigenschaft gemäß der Spezifikation ecma-international.org/ecma-262/5.1/#sec-15.1.1.3
therealrootuser
1
In früheren Versionen von JavaScript waren 'undefined' und 'NaN' veränderbare Variablen, die neu definiert oder anderen Werten zugewiesen werden konnten . Das war eine schlechte Sache. Es wurde in ECMAScript 5
behoben
29
"key" in obj

Testet wahrscheinlich nur Objektattributwerte, die sich stark von Array-Schlüsseln unterscheiden

user2320522
quelle
Dieser Code gilt auch für einen Schlüssel, der im Klassenprototyp definiert ist: Funktion A () {}; A.prototype.b = 2; var a = new A (); Dann ist 'b' in a wahr. Während a.hasOwnProperty ('b') natürlich falsch ist.
Alexander
24

Drei Möglichkeiten, um zu überprüfen, ob eine Eigenschaft in einem Javascript-Objekt vorhanden ist:

  1. !!obj.theProperty
    Konvertiert den Wert in bool. Gibt truefür alle außer dem falseWert zurück
  2. ' theProperty' in obj Gibt
    true zurück, wenn die Eigenschaft existiert, unabhängig von ihrem Wert (auch leer).
  3. obj.hasOwnProperty('theProperty')
    Überprüft nicht die Prototypenkette. (Da alle Objekte die toStringMethode haben, geben 1 und 2 true zurück, während 3 false zurückgeben kann.)

Referenz:

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

Lavi Avigdor
quelle
!! obj.theProperty schlägt fehl, wenn der Wert undefiniert ist. Beispiel:var a = {a : undefined, b : null}; !!a.a **will return false**
ARJUN
from review: !!obj.thePropertyist keine Lösung, um zu überprüfen, ob ein Objekt eine Eigenschaft mit dem Namen hat theProperty. Es schlägt fehl undefined, 0NaN""
wenn vor
15

Wenn Sie die Bibliothek underscore.js verwenden, werden Objekt- / Array-Operationen einfach.

In Ihrem Fall kann die Methode _.has verwendet werden. Beispiel:

yourArray = {age: "10"}

_.has(yourArray, "age")

gibt true zurück

Aber,

_.has(yourArray, "invalidKey")

gibt false zurück

vatsal
quelle
15

Antworten:

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

Erläuterung:

Der inBediener prüft, ob der Schlüssel im Objekt vorhanden ist. Wenn Sie überprüft haben, ob der Wert undefiniert ist if (myObj["key"] === 'undefined'), können Probleme auftreten, da möglicherweise ein Schlüssel mit dem undefinedWert in Ihrem Objekt vorhanden ist.

Aus diesem Grund ist es viel besser, zuerst den inOperator zu verwenden und dann den Wert im Schlüssel zu vergleichen, sobald Sie bereits wissen, dass er existiert.

Webeng
quelle
12

Hier ist eine Hilfsfunktion, die ich sehr nützlich finde

Dies keyExists(key, search)kann verwendet werden, um einen Schlüssel in Objekten oder Arrays einfach nachzuschlagen!

Übergeben Sie ihm einfach den Schlüssel, den Sie suchen möchten, und suchen Sie nach obj (dem Objekt oder Array), in dem Sie es finden möchten.

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

Es war ziemlich zuverlässig und funktioniert gut browserübergreifend.

jaredwilli
quelle
6
Dies scheint etwas verwirrt zu sein: Erstens sucht diese Methode beim Durchsuchen eines Arrays nach einem Wert , nicht nach einem Schlüssel. Zweitens, warum sollten Sie ein Array wie dieses durchlaufen, wenn Sie die integrierte Array.indexOfMethode verwenden können? (wenn Sie nach einem Wert suchen, das ist)
Nick F
9

vanila js

yourObjName.hasOwnProperty(key) : true ? false;

Wenn Sie überprüfen möchten, ob das Objekt in es2015 mindestens eine Eigenschaft hat

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

ES6-Lösung

mit Array#someund Object.keys. Es wird true zurückgegeben, wenn ein bestimmter Schlüssel im Objekt vorhanden ist, oder false, wenn dies nicht der Fall ist.

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

Einzeiliges Beispiel.

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

freundlicher Benutzer
quelle
1
Bei nicht numerierbaren Eigenschaften des Objekts schlägt dies fehl.
Sid
@ Sid Gib mir ein Beispiel.
freundlicher Benutzer
Bitte schön. let joshua = {Name: 'Joshua', Adresse: 'London'}; Object.defineProperty (joshua, 'isMarried', {value: true, enumerable: false}); console.log ('isMarried' in Object.keys (joshua))
Sid
Ich wende Ihre Lösung auf mein Objekt an. Sollte es nicht für die erste Ausgabe wahr sein? console.log (Object.keys (joshua) .some (v => v == 'isMarried')); console.log (joshua.isMarried);
Sid
1
Es tut mir leid, aber haben Sie die Ausgabe der zweiten Konsolenanweisung überprüft? Object.defineProperty entspricht dem Festlegen der Eigenschaft mithilfe der Punktnotation.
Sid
6

Wir können benutzen - hasOwnProperty.call(obj, key);

Der unterstrich.js Weg -

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

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

Der einfachste Weg zu überprüfen ist

"key" in object

zum Beispiel:

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

Der Rückgabewert als true impliziert, dass der Schlüssel im Objekt vorhanden ist.

shekhardtu
quelle
4

Für diejenigen, die lodashin ihr Projekt aufgenommen haben:
Es gibt eine lodash _.get- Methode, die versucht, "tiefe" Schlüssel zu erhalten:

Ruft den Wert am Pfad des Objekts ab. Wenn der aufgelöste Wert undefiniert ist, wird der Standardwert an seiner Stelle zurückgegeben.

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>


Dadurch wird effektiv überprüft, ob dieser Schlüssel, wie tief er auch sein mag , definiert ist, und es wird kein Fehler ausgegeben, der den Programmfluss beeinträchtigen könnte, wenn dieser Schlüssel nicht definiert ist.

vsync
quelle
4

Dies prüft zwar nicht unbedingt, ob ein Schlüssel vorhanden ist, prüft jedoch die Richtigkeit eines Wertes. Welche undefinedund nullfallen unter.

Boolean(obj.foo)

Diese Lösung funktioniert am besten für mich, da ich Typoskript verwende und solche Zeichenfolgen verwende 'foo' in objoder um obj.hasOwnProperty('foo')zu überprüfen, ob ein Schlüssel vorhanden ist oder nicht, bietet mir Intellisense nicht.

Realappie
quelle
3

Wenn Sie in einer beliebigen Tiefe eines Objekts nach einem Schlüssel suchen und Falsey-Werte berücksichtigen möchten, ziehen Sie diese Zeile für eine Dienstprogrammfunktion in Betracht:

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

Ergebnisse

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

Siehe auch dieses NPM-Paket: https://www.npmjs.com/package/has-deep-value

Alex
quelle
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
quelle
3

In der 'Array'-Welt können wir Indizes als eine Art Schlüssel betrachten. Was überrascht, ist, dass der inOperator (der für Objekte eine gute Wahl ist) auch mit Arrays arbeitet. Der zurückgegebene Wert für nicht vorhandenen Schlüssel istundefined

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
quelle
2

yourArray.indexOf (yourArrayKeyName)> -1

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

fruit.indexOf('apple') > -1

wahr


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

fruit.indexOf('apple1') > -1

falsch

Anupam Maurya
quelle
0

Dieses Beispiel kann die Unterschiede zwischen verschiedenen Methoden demonstrieren. Ich hoffe, es wird Ihnen helfen, das richtige für Ihre Bedürfnisse auszuwählen:

// 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"]
Alexander
quelle
-1

Neue großartige Lösung mit 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

Überprüfen Sie die andere Verwendung von JavaScript Destructuring

NAVIN
quelle