1872 Stimmen

Wie prüfe ich, ob ein Objekt eine bestimmte Eigenschaft in JavaScript hat?

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?

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 y hasOwnProperty herausgekommen Weg für mich langsamer als die anderen (98 % langsamer). Ich bin nicht überrascht über hasOwnProperty langsamer zu sein, aber ich bin überrascht über in .

1751voto

John Resig Punkte 34001

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.

5 Stimmen

@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.

0 Stimmen

@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.

0 Stimmen

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).

325voto

Brian M. Hunt Punkte 75888

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

73 Stimmen

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".

13 Stimmen

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.

10 Stimmen

Et lodash Die Versionen des Programms funktionieren damit: .has(undefined, 'someKey') => false während underscore gibt zurück. undefined

232voto

Whisher Punkte 28374

Utilizar:

var x = {
  'key': 1
};

if ('key' in x) {
  console.log('has');
}

19 Stimmen

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.)

1 Stimmen

@ 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/

4 Stimmen

Betreiber in prüft auch gegen Prototypeigenschaften, während hasOwnProperty iteriert nur benutzerdefinierte Eigenschaften. Referenz: developer.mozilla.org/de-US/docs/Web/JavaScript/Reference/

146voto

Konrad Rudolph Punkte 503837

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 …
})();

6 Stimmen

Nur aus Neugier, da void 0 wird definiert, um die kanonische undefined könnte man tun x.attribute !== void 0 ?

1 Stimmen

Brian: Ich bin kein Experte, aber das scheint ein cleverer Weg zu sein, es richtig zu machen.

42 Stimmen

Wenn der berühmte "jemand anders" neu definiert hat, was "undefiniert" ist, wäre es wohl am besten, DIESEN Code neu zu schreiben.

61voto

enobrev Punkte 21804
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';
};

2 Stimmen

Ich glaube nicht, dass das gut genug ist. x.hasOwnProperty('toString') === true;

0 Stimmen

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.

1 Stimmen

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.com

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.

Powered by:

X