Gibt es einen praktischen Unterschied [zwischen meinen Beispielen]?
Der Benutzer hat möglicherweise ein JavaScript-Objekt erstellt Object.create(null)
, das eine null
[[Prototype]]
Kette hat und daher nicht hasOwnProperty()
verfügbar ist. Die Verwendung Ihres zweiten Formulars funktioniert aus diesem Grund nicht.
Es ist auch ein sicherer Hinweis auf Object.prototype.hasOwnProperty()
(und auch kürzer).
Sie können sich vorstellen, dass jemand getan hat ...
var someObject = {
hasOwnProperty: function(lol) {
return true;
}
};
Was einen hasProp(someObject)
Fehler verursachen würde, wenn es wie Ihr zweites Beispiel implementiert worden wäre (es würde diese Methode direkt auf dem Objekt finden und diese aufrufen, anstatt an delegiert zu werden Object.prototype.hasOwnProperty
).
Es ist jedoch weniger wahrscheinlich, dass jemand die Object.prototype.hasOwnProperty
Referenz überschrieben hat .
Und da wir gerade dabei sind, warum definieren wir diese Funktion überhaupt?
Siehe oben.
Ist es nur eine Frage von Verknüpfungen und lokalem Caching des Immobilienzugriffs für (leichte) Leistungssteigerungen ...
Theoretisch mag es schneller gehen , da die [[Prototype]]
Kette nicht befolgt werden muss, aber ich vermute, dass dies vernachlässigbar ist und nicht der Grund, warum die Implementierung der Grund dafür ist.
... oder fehlen mir Fälle, in denen
hasOwnProperty
Objekte verwendet werden könnten, die diese Methode nicht haben?
hasOwnProperty()
existiert am Object.prototype
, kann aber überschrieben werden. Jedes native JavaScript-Objekt (aber Host-Objekte können dies nicht garantieren) siehe RobGs ausführliche Erklärung ) hat Object.prototype
als letztes Objekt in der Kette zuvor null
(außer natürlich für das von zurückgegebene Objekt Object.create(null)
).
const hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
Es mag wie Haarspalterei erscheinen, aber es gibt einen Unterschied zwischen Javascript (der Oberbegriff für ECMAScript-Implementierungen) und ECMAScript (die Sprache, die für Javascript-Implementierungen verwendet wird). Es ist ECMAScript, das ein Vererbungsschema definiert, nicht Javascript, sodass nur native ECMAScript-Objekte dieses Vererbungsschema implementieren müssen.
Ein laufendes Javascript-Programm besteht mindestens aus den integrierten ECMAScript-Objekten (Objekt, Funktion, Nummer usw.) und wahrscheinlich einigen nativen Objekten (z. B. Funktionen). Möglicherweise sind auch einige Hostobjekte vorhanden (z. B. DOM-Objekte in einem Browser oder andere Objekte in anderen Hostumgebungen).
Während integrierte und native Objekte das in ECMA-262 definierte Vererbungsschema implementieren müssen, tun dies Host-Objekte nicht. Daher sind nicht alle Objekte in einer JavaScript - Umgebung muss von erben Object.prototype . Beispielsweise lösen Hostobjekte im IE, die als ActiveX-Objekte implementiert sind, Fehler aus, wenn sie als native Objekte behandelt werden (daher wird try..catch zum Initialisieren von MS XMLHttpRequest-Objekten verwendet). Einige DOM-Objekte (wie NodeLists im IE im Quirks-Modus), die an Array-Methoden übergeben werden, werfen Fehler auf. DOM-Objekte in IE 8 und niedriger haben kein ECMAScript-ähnliches Vererbungsschema usw.
Daher sollte nicht davon ausgegangen werden, dass alle Objekte in einer Javascript-Umgebung von Object.prototype erben.
Dies gilt zumindest nicht für bestimmte Hostobjekte im IE im Mackenmodus (und IE 8 und niedriger immer).
Vor diesem Hintergrund lohnt es sich zu überlegen, warum ein Objekt möglicherweise über eine eigene hasOwnProperty- Methode verfügt und ob es ratsam ist, eine andere aufzurufen ratsam ist , stattdessen hasOwnProperty- Methode aufzurufen , ohne vorher zu testen, ob dies eine gute Idee ist oder nicht.
Bearbeiten
Ich vermute, dass der Grund für die Verwendung darin
Object.prototype.hasOwnProperty.call
besteht, dass Host-Objekte in einigen Browsern keine hasOwnProperty- Methode haben. Die Verwendung von call und der integrierten Methode ist eine Alternative. Dies generisch zu tun, scheint jedoch aus den oben genannten Gründen keine gute Idee zu sein.Wo Host - Objekte betroffen sind, die in kann Operator Objekte allgemein Test verwendet werden, zB
Eine Alternative (getestet in IE6 und anderen):
Auf diese Weise rufen Sie nur die integrierte hasOwnProperty auf wo das Objekt sie nicht hat (geerbt oder anderweitig).
Wenn jedoch ein Objekt keinen hat
hasOwnProperty
Methode, ist es wahrscheinlich genauso geeignet die die Verwendung in Bediener als das Objekt mit hohen Wahrscheinlichkeit kein Erbteil Schema hat und alle Eigenschaften sind auf dem Objekt (das ist nur eine Annahme , obwohl), zB die In Operator ist eine gängige (und scheinbar erfolgreiche) Methode zum Testen der DOM-Objektunterstützung für Eigenschaften.quelle
in
führt keinehasOwnProperty()
Suche durch. Ich vermute, dass die von Ihnen gesuchte Eigenschaft in der Prototypenkette vorhanden war.hasOwnProperty
das resultierende Objekt direkt aufzurufen , da dies ein böswilliger Client könnte Senden Sie einen JSON-Wert wie{"hasOwnProperty": 1}
und führen Sie zum Absturz des Servers.Wenn die Möglichkeit besteht, dass ein Objekt eine Eigenschaft mit diesem Namen hat, muss eine externe hasOwnProperty verwendet werden, um korrekte Ergebnisse zu erhalten:
Sie können die folgenden Codefragmente kopieren und in die Browserkonsole einfügen, um ein besseres Verständnis zu erhalten
Gibt immer false zurück
Verwenden Sie die hasOwnProperty eines anderen Objekts und rufen Sie sie mit diesem Set auf foo auf
Zu diesem Zweck kann auch die Eigenschaft hasOwnProperty aus dem Object- Prototyp verwendet werden
quelle
hasOwnProperty
Retouren erfolgttrue
.Die Informationen in beiden vorhandenen Antworten sind genau richtig. Die Verwendung von:
wird ein paar mal erwähnt. Es ist zu beachten, dass die
hasOwnProperty
Implementierungen nur dann true zurückgeben, wenn die Eigenschaft direkt auf dem zu testenden Objekt enthalten ist.Der
in
Bediener wird auch die Prototypenkette überprüfen.Dies bedeutet, dass Instanzeigenschaften true zurückgeben, wenn sie an
hasOwnProperty
where übergeben werden, da die Prototypeigenschaften false zurückgeben.Wenn Sie den
in
Operator verwenden, geben sowohl die Instanz- als auch die Prototyp-Eigenschaften true zurück.quelle