JavaScript-Objekterkennung: Punktsyntax versus 'in' Schlüsselwort

  • Ich habe zwei Möglichkeiten gesehen, um festzustellen, ob ein UA eine bestimmte JS-Eigenschaft implementiert: if(object.property) und if('property' in object).

    möchte ich hören Sie Meinungen darüber, was besser und vor allem warum ist. Ist einer eindeutig besser als der andere? Gibt es mehr als nur zwei Möglichkeiten, die Objekteigenschaften zu ermitteln? Bitte behandeln Sie Browserunterstützung, Fallstricke, Ausführungsgeschwindigkeit und dergleichen anstelle von Ästhetik.

    Bearbeiten: Leser sollten die Tests bei jsperf.com/object-detection

    02 August 2013
    Nicholas Shanks
5 answers
    • if(object.property)

      schlägt fehl, wenn es nicht gesetzt ist (was Sie möchten), und in Fällen, in denen ein falsey-Wert festgelegt wurde, z undefined, null, 0 etc (was Sie nicht wollen).

       var object = {property: 0};
      if(object.isNotSet) { ... } // will not run
      if(object.property) { ... } // will not run
       
    • if('property' in object)

      ist etwas besser, da es tatsächlich zurückgeben wird, ob das Objekt wirklich die Eigenschaft hat, nicht nur durch das Betrachten seiner Wert.

       var object = {property: 0};
      if('property' in object) { ... } // will run
      if('toString' in object) { ... } // will also run; from prototype
       
    • if(object.hasOwnProperty('property'))

      ist sogar noch besser, da Sie zwischen Instanzeigenschaften und Prototypeneigenschaften unterscheiden können.

       var object = {property: 0};
      if(object.hasOwnProperty('property')) { ... } // will run
      if(object.hasOwnProperty('toString')) { ... } // will not run
       

    Ich würde sagen, dass Leistung hier kein großes Problem darstellt, es sei denn, Sie prüfen tausende Male eine Sekunde, aber in diesem Fall sollten Sie eine andere Codestruktur in Betracht ziehen. Alle diese Funktionen / Syntaxe werden von aktuellen Browsern unterstützt: hasOwnProperty gibt es auch schon lange.


    Bearbeiten: Das können Sie auch Erstellen Sie eine allgemeine Funktion, um die Existenz einer Eigenschaft zu überprüfen, indem Sie etwas (auch Dinge, die keine Objekte sind) als Objekt wie folgt übergeben:

     function has(obj, prop) {
        return Object.prototype.hasOwnProperty.call(obj, prop);
    }
     

    Nun funktioniert es:

     has(window, 'setTimeout'); // true
     

    auch wenn window.hasOwnProperty === undefined (was der Fall ist) in IE Version 8 oder niedriger).

    10 August 2017
    robinCTSSlopeside Creative
  • Es hängt wirklich davon ab, was Sie erreichen möchten. Sprechen Sie über Host-Objekte (wie window und DOM-Knoten)? Wenn ja, ist die sicherste Prüfung typeof. Dies funktioniert für alle mir bekannten Host-Objekte:

      if (typeof object.property != "undefined") { ... }
     

    Hinweise:

    • Vermeiden Sie object.hasOwnProperty() für Hostobjekte, da Hostobjekte nicht verpflichtet sind, von Object.prototype zu erben, und daher möglicherweise keine hasOwnProperty() haben. Methode (und in IE 9 tatsächlich nicht).
    • Ein einfacher boolescher Zwang (zB if (object.property) { ... }) ist ein schlechter Test für das Vorhandensein einer Eigenschaft, da dies der Fall ist geben falsche Negative für falsche Werte. Bei einem leeren Textbereich führt if (textarea.selectionStart) { ... } zum Beispiel den Block nicht aus, obwohl die Eigenschaft vorhanden ist. Bei einigen Host-Objekteigenschaften wird außerdem in älteren IE-Versionen ein Fehler ausgegeben, wenn versucht wird, einen Boolean zu erzwingen (z. B. var xhr = new ActiveXObject("Microsoft.XMLHTTP"); if (xhr.responseXML) { ... }).
    • Der Operator in ist ein besserer Test für das Vorhandensein einer Eigenschaft, es gibt jedoch auch keine Garantie, dass sie in Host-Objekten unterstützt wird.
    • Ich empfehle, die Leistung für diese Art von Aufgabe nicht in Betracht zu ziehen. Wählen Sie die sicherste Option für Ihr Projekt und optimieren Sie erst später. Es wird mit Sicherheit sehr viel bessere Kandidaten für die Optimierung geben als die Prüfung der Eigenschaften des Objekts.

    Für weitere Informationen empfehle ich dieser exzellente Artikel von Peter Michaux .

    24 August 2011
    Tim Down
  • Auf jeden Fall ist if ('property' in object) der richtige Weg. Das prüft tatsächlich, ob sich die Eigenschaft in dem Objekt befindet (oder in ihrer Prototypkette, mehr dazu weiter unten).

    if (object.property) dagegen zwingt 'property' in ein Wahrheits- / Flaschewert. Wenn die Eigenschaft nicht festgelegt ist, wird "undefined" zurückgegeben. Dies wird in false gezwungen und scheint zu funktionieren. Dies schlägt jedoch auch für eine Reihe anderer festgelegter Eigenschaftswerte fehl. Javascript ist bekanntermaßen inkonsistent in dem, was es als wahr und falsch behandelt.

    Wie bereits gesagt, wird 'property' in 'object' als wahr zurückgegeben, wenn es sich irgendwo in der Prototypkette befindet. Wenn Sie testen möchten, dass sich das Objekt selbst befindet und nicht an einer anderen Stelle in der Kette, verwenden Sie die Methode hasOwnProperty wie folgt:

     if (object.hasOwnProperty('property')) ...
     
    24 August 2011
    Ben Lee
  • Damit können Sie window.hasOwnProperty verwenden, um sich entweder auf sich selbst oder auf etwas anderes zu beziehen, unabhängig von Ihrem Skript-Host.

    >
    22 March 2012
    Fordi
  • Die erste schlägt fehl, wenn "property" den Wert 0 hat. Um sicherzustellen, dass tatsächlich eine Eigenschaft vorhanden ist, müssen Sie object.property !== undefined überprüfen oder das in-Schlüsselwort verwenden.

    [Edit]

    Es gibt auch die hasOwnProperty-Funktion, aber ich habe diese Funktion noch nie verwendet, daher kann ich nicht viel darüber sagen . Ich denke, es wird nicht wahr zurückgegeben, wenn die Eigenschaft in einem Prototyp festgelegt ist, was Sie manchmal möchten, manchmal aber nicht.

    24 August 2011
    Alxandr