Wie prüfe ich, ob ein Objekt eine bestimmte Eigenschaft in JavaScript hat?
Bedenken Sie:
x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}
Ist das der beste Weg?
Wie prüfe ich, ob ein Objekt eine bestimmte Eigenschaft in JavaScript hat?
Bedenken Sie:
x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}
Ist das der beste Weg?
Ich bin wirklich verwirrt von den Antworten, die gegeben wurden - die meisten von ihnen sind schlichtweg falsch. Natürlich kann man Objekteigenschaften haben, die undefinierte, null oder falsche Werte haben. Also reduziert man einfach die Eigenschaftsprüfung auf typeof this[property]
oder, noch schlimmer, x.key
wird Ihnen völlig irreführende Ergebnisse liefern.
Das hängt davon ab, was Sie suchen. Wenn Sie wissen wollen, ob ein Objekt physisch eine Eigenschaft enthält (und diese nicht von irgendwo oben in der Prototypenkette stammt), dann object.hasOwnProperty
ist der richtige Weg. Alle modernen Browser unterstützen es. (In älteren Versionen von Safari - 2.0.1 und älter - fehlte sie, aber diese Versionen des Browsers werden kaum noch verwendet).
Wenn Sie nach einer Eigenschaft eines Objekts suchen, die iterierbar ist (wenn Sie über die Eigenschaften des Objekts iterieren, wird sie angezeigt), dann tun Sie das: prop in object
wird die gewünschte Wirkung erzielen.
Da die Verwendung von hasOwnProperty
ist wahrscheinlich das, was Sie wollen, und wenn man bedenkt, dass Sie vielleicht eine Ausweichmethode brauchen, stelle ich Ihnen die folgende Lösung vor:
var obj = {
a: undefined,
b: null,
c: false
};
// a, b, c all found
for ( var prop in obj ) {
document.writeln( "Object1: " + prop );
}
function Class(){
this.a = undefined;
this.b = null;
this.c = false;
}
Class.prototype = {
a: undefined,
b: true,
c: true,
d: true,
e: true
};
var obj2 = new Class();
// a, b, c, d, e found
for ( var prop in obj2 ) {
document.writeln( "Object2: " + prop );
}
function hasOwnProperty(obj, prop) {
var proto = obj.__proto__ || obj.constructor.prototype;
return (prop in obj) &&
(!(prop in proto) || proto[prop] !== obj[prop]);
}
if ( Object.prototype.hasOwnProperty ) {
var hasOwnProperty = function(obj, prop) {
return obj.hasOwnProperty(prop);
}
}
// a, b, c found in modern browsers
// b, c found in Safari 2.0.1 and older
for ( var prop in obj2 ) {
if ( hasOwnProperty(obj2, prop) ) {
document.writeln( "Object2 w/ hasOwn: " + prop );
}
}
Dies ist eine funktionierende, browserübergreifende Lösung für hasOwnProperty
mit einer Einschränkung: Es ist nicht in der Lage, zwischen Fällen zu unterscheiden, in denen eine identische Eigenschaft im Prototyp und in der Instanz vorhanden ist - es wird einfach angenommen, dass sie vom Prototyp stammt. Sie können es je nach Situation nachsichtiger oder strenger machen, aber zumindest sollte dies hilfreicher sein.
@grantwparks Wenn Sie ein einfaches Slider-Plugin erstellen und das Vorhandensein eines Optionselements überprüfen wollen, dann könnte dies in der Tat mehr als nötig sein. Sie können einfach etwas tun wie var w = opts.w || 100;
. Wenn Sie aber eine Art Bibliothek suchen, müssen Sie vielleicht an einigen Stellen etwas weiter gehen.
@kralco626: Ja, heutzutage halte ich es für ziemlich sicher, mit hasOwnProperty() zu arbeiten - aber für eine wirklich sichere browserübergreifende Lösung sollten Sie Johns Lösung verwenden.
Was ist mit vorübergehend ändern __proto__
zu null? Einfache Impl: function hasOwnProperty(obj, prop) { var temp = obj.__proto__; obj.__proto__ = null; var ret = prop in obj; obj.__proto__ = temp; return ret; }
(Koffer mit obj.constructor.prototype
sollte hinzugefügt werden).
Con Underscore.js oder ( noch besser ) Lodash :
_.has(x, 'key');
Welche Anrufe Object.prototype.hasOwnProperty
aber (a) ist kürzer in der Schreibweise und (b) verwendet "einen sicheren Verweis auf hasOwnProperty
" (d.h. es funktioniert auch, wenn hasOwnProperty
überschrieben wird).
Insbesondere definiert Lodash _.has
comme :
function has(object, key) {
return object ? hasOwnProperty.call(object, key) : false;
}
// hasOwnProperty = Object.prototype.hasOwnProperty
Ich würde vermuten, es ist, weil "fügen Sie diese Bibliothek" ist selten eine beliebte Lösung, auch wenn die Frage ist über komplexe DOM-Manipulation und die Antwort ist "gehen Sie verwenden jQuery".
Ich verstehe Ihren Standpunkt, @sudowned, danke. Übrigens, wenn man nicht die gesamte Lodash-Bibliothek einbinden möchte, könnte man Teilkomponenten kompilieren oder npm install lodash.has
das ein npm-Modul mit nur einem has
Funktion, die nach dem Mining auf 175 Byte kompiliert wird. Es ist auch aufschlussreich, sich die lodash.has/index.js
um zu sehen, wie eine sehr beliebte und vertrauenswürdige Bibliothek funktioniert.
Et lodash
Die Versionen des Programms funktionieren damit: .has(undefined, 'someKey') => false
während underscore
gibt zurück. undefined
Zu beachten ist, dass es mit "Objekten" im engeren Sinne arbeitet, d.h. als {} deklariert oder mit einem Konstruktor erstellt wird, es akzeptiert keine Arrays oder Primitive. Nicht, dass der OP es benötigt hätte, aber einige andere Antworten zeigen Techniken, die breiter angelegt sind (Arbeit mit Arrays, Strings usw.)
@ Danke für den Hinweis (in der akzeptierten Antwort wird nicht näher erläutert, warum man die in
Betreiber oder nicht. Beachten Sie auch, dass der in
Der Betreiber hat eine hervorragende Browserunterstützung IE 5.5+, Chrome 1.0+, Firefox 1.0+, Safari 3.0+
stackoverflow.com/questions/2920765/
Betreiber in
prüft auch gegen Prototypeigenschaften, während hasOwnProperty
iteriert nur benutzerdefinierte Eigenschaften. Referenz: developer.mozilla.org/de-US/docs/Web/JavaScript/Reference/
Hinweis : Das Folgende ist heute dank des Strict Mode weitgehend überholt, und hasOwnProperty
. Die korrekte Lösung ist die Verwendung des Strict-Modus und die Überprüfung auf das Vorhandensein einer Eigenschaft mit obj.hasOwnProperty
. Diese Antwort vor beides, zumindest in der weit verbreiteten Form (ja, es ist so alt). Nehmen Sie das Folgende als eine historische Anmerkung.
Bitte beachten Sie, dass undefined
ist (leider) no ein reserviertes Wort in JavaScript, wenn Sie nicht den Strict-Modus verwenden. Daher könnte jemand (natürlich jemand anderes) auf die grandiose Idee kommen, es neu zu definieren und damit Ihren Code zu zerstören.
Eine robustere Methode ist daher die folgende:
if (typeof(x.attribute) !== 'undefined')
Auf der anderen Seite ist diese Methode sehr viel ausführlicher und auch langsamer :-/
Eine gängige Alternative besteht darin, sicherzustellen, dass undefined
es eigentlich undefiniert, z.B. durch Einfügen des Codes in eine Funktion, die einen zusätzlichen Parameter akzeptiert, der undefined
die nicht mit einem Wert versehen ist. Um sicherzugehen, dass kein Wert übergeben wird, können Sie es einfach selbst sofort aufrufen, z. B.:
(function (undefined) {
… your code …
if (x.attribute !== undefined)
… mode code …
})();
Nur aus Neugier, da void 0
wird definiert, um die kanonische undefined
könnte man tun x.attribute !== void 0
?
Brian: Ich bin kein Experte, aber das scheint ein cleverer Weg zu sein, es richtig zu machen.
Wenn der berühmte "jemand anders" neu definiert hat, was "undefiniert" ist, wäre es wohl am besten, DIESEN Code neu zu schreiben.
if (x.key !== undefined)
Armin Ronacher scheint bereits mir zuvorgekommen , sondern:
Object.prototype.hasOwnProperty = function(property) {
return this[property] !== undefined;
};
x = {'key': 1};
if (x.hasOwnProperty('key')) {
alert('have key!');
}
if (!x.hasOwnProperty('bar')) {
alert('no bar!');
}
Eine sicherere, aber langsamere Lösung, wie hervorgehoben por Konrad Rudolph y Armin Ronacher wäre:
Object.prototype.hasOwnProperty = function(property) {
return typeof this[property] !== 'undefined';
};
Nicht um zu widersprechen, sondern um zu verstehen. Gibt es einen Punkt, an dem x.hasOwnProperty etwas anderes als ein boolesches true oder false zurückgeben würde? Wenn nicht, sollte der Code wie gepostet jedes Mal funktionieren. Ich nehme an, vielleicht, wenn die Methode überschrieben wurden, aber dann, auf das Ergebnis verlassen würde nie zuverlässig sein, es sei denn, Sie kennen die überschreibende Methode.
Ich glaube, wir haben ein Missverständnis. Ich meine, dass mit Ihrer Methode, es würde sagen, dass "toString" seine eigene Eigenschaft ist, aber es ist nicht.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
32 Stimmen
Ich habe einen jsperf-Test mit den Antworten aller geschrieben, um zu sehen, wer am schnellsten ist: jsperf.com/wörterbuch-enthaelt-schluessel
0 Stimmen
('propertyName' in Object) ? 'Eigenschaft ist vorhanden' : 'Eigenschaft ist nicht vorhanden'
2 Stimmen
@styfle danke für den jsperf-Test.
in
yhasOwnProperty
herausgekommen Weg für mich langsamer als die anderen (98 % langsamer). Ich bin nicht überrascht überhasOwnProperty
langsamer zu sein, aber ich bin überrascht überin
.4 Stimmen
Es gibt einen neuen Vorschlag für Stufe 3,
Object.hasOwn
die einige der Probleme derObject.prototype.hasOwnProperty
.