Object
Der Object
-Typ stellt einen der Datentypen von JavaScript dar. Er wird verwendet, um verschiedene, benannte Sammlungen und komplexere Entitäten zu speichern. Objekte können mit dem Object()
-Konstruktor oder der Objekt-Initialisierer-/Literalsyntax erstellt werden.
Beschreibung
Nahezu alle Objekte in JavaScript sind Instanzen von Object
; ein typisches Objekt erbt Eigenschaften (einschließlich Methoden) von Object.prototype
, obwohl diese Eigenschaften überschrieben werden können. Die einzigen Objekte, die nicht von Object.prototype
erben, sind jene mit null
-Prototyp oder jene, die von anderen null
-Prototype-Objekten abstammen.
Änderungen am Object.prototype
-Objekt werden durch Prototypverkettung von allen Objekten gesehen, es sei denn, die von diesen Änderungen betroffenen Eigenschaften und Methoden werden weiter entlang der Prototypkette überschrieben. Dies stellt eine sehr leistungsstarke, jedoch potenziell gefährliche Möglichkeit dar, das Verhalten von Objekten zu überschreiben oder zu erweitern. Um es sicherer zu machen, ist Object.prototype
das einzige Objekt in der Kern-JavaScript-Sprache mit einem unveränderlichen Prototyp — der Prototyp von Object.prototype
ist immer null
und nicht veränderbar.
Eigenschaften des Objektprototyps
Sie sollten vermeiden, eine Methode von Object.prototype
direkt von der Instanz aufzurufen, insbesondere jene, die nicht polymorph sein sollen (d. h. nur ihr ursprüngliches Verhalten ist sinnvoll und kein abgeleitetes Objekt könnte sie in sinnvoller Weise überschreiben). Alle Objekte, die von Object.prototype
abstammen, können eine eigene benutzerdefinierte Eigenschaft definieren, die denselben Namen hat, aber völlig andere Semantik als erwartet. Diese Eigenschaften werden außerdem nicht von null
-Prototypobjekten geerbt. Alle modernen JavaScript-Dienstprogramme zum Arbeiten mit Objekten sind statisch. Genauer gesagt:
valueOf()
,toString()
undtoLocaleString()
sind polymorph und Sie sollten erwarten, dass das Objekt seine eigene Implementierung mit sinnvollem Verhalten definiert, sodass Sie sie als Instanzmethoden aufrufen können.valueOf()
undtoString()
werden jedoch in der Regel implizit durch Typumwandlung aufgerufen, und Sie müssen sie in Ihrem Code nicht selbst aufrufen.__defineGetter__()
,__defineSetter__()
,__lookupGetter__()
und__lookupSetter__()
sind veraltet und sollten nicht verwendet werden. Verwenden Sie stattdessen die statischen AlternativenObject.defineProperty()
undObject.getOwnPropertyDescriptor()
.- Die
__proto__
-Eigenschaft ist veraltet und sollte nicht verwendet werden. Die AlternativenObject.getPrototypeOf()
undObject.setPrototypeOf()
sind statische Methoden. - Die Methoden
propertyIsEnumerable()
undhasOwnProperty()
können mit den statischen MethodenObject.getOwnPropertyDescriptor()
bzw.Object.hasOwn()
ersetzt werden. - Die Methode
isPrototypeOf()
kann in der Regel mitinstanceof
ersetzt werden, wenn Sie dieprototype
-Eigenschaft eines Konstruktors prüfen.
Wo eine semantisch äquivalente statische Methode nicht existiert, oder wenn Sie wirklich die Object.prototype
-Methode verwenden wollen, sollten Sie die Object.prototype
-Methode stattdessen direkt mit call()
auf Ihrem Zielobjekt aufrufen, um zu verhindern, dass das Objekt eine überschreibende Eigenschaft hat, die unerwartete Ergebnisse produziert.
const obj = {
foo: 1,
// You should not define such a method on your own object,
// but you may not be able to prevent it from happening if
// you are receiving the object from external input
propertyIsEnumerable() {
return false;
},
};
obj.propertyIsEnumerable("foo"); // false; unexpected result
Object.prototype.propertyIsEnumerable.call(obj, "foo"); // true; expected result
Eine Eigenschaft aus einem Objekt löschen
Es gibt keine Methode in einem Object selbst, um seine eigenen Eigenschaften zu löschen (wie etwa Map.prototype.delete()
). Dazu muss der delete
-Operator verwendet werden.
null-Prototyp-Objekte
Fast alle Objekte in JavaScript erben letztlich von Object.prototype
(siehe Vererbung und die Prototypkette). Sie können jedoch null
-Prototypobjekte mit Object.create(null)
oder der Objekt-Initialisierungssyntax mit __proto__: null
erstellen (bemerken Sie: der __proto__
-Schlüssel in Objektliteralen ist anders als die veraltete Object.prototype.__proto__
-Eigenschaft). Sie können auch den Prototyp eines bestehenden Objekts in null
ändern, indem Sie Object.setPrototypeOf(obj, null)
aufrufen.
const obj = Object.create(null);
const obj2 = { __proto__: null };
Ein Objekt mit einem null
-Prototyp kann sich unerwartet verhalten, da es keine Objekteigenschaften von Object.prototype
erbt. Dies gilt insbesondere beim Debuggen, da gängige Objekteigenschaften-Konvertierungs-/Erkennungs-Dienstprogramme Fehler erzeugen können oder Informationen verlieren (insbesondere bei der Verwendung von stillen Fehlerfallen, die Fehler ignorieren).
Zum Beispiel macht das Fehlen von Object.prototype.toString()
das Debuggen oft unlösbar:
const normalObj = {}; // create a normal object
const nullProtoObj = Object.create(null); // create an object with "null" prototype
console.log(`normalObj is: ${normalObj}`); // shows "normalObj is: [object Object]"
console.log(`nullProtoObj is: ${nullProtoObj}`); // throws error: Cannot convert object to primitive value
alert(normalObj); // shows [object Object]
alert(nullProtoObj); // throws error: Cannot convert object to primitive value
Andere Methoden werden ebenfalls fehlschlagen.
normalObj.valueOf(); // shows {}
nullProtoObj.valueOf(); // throws error: nullProtoObj.valueOf is not a function
normalObj.hasOwnProperty("p"); // shows "true"
nullProtoObj.hasOwnProperty("p"); // throws error: nullProtoObj.hasOwnProperty is not a function
normalObj.constructor; // shows "Object() { [native code] }"
nullProtoObj.constructor; // shows "undefined"
Wir können die toString
-Methode zum null-Prototyp-Objekt hinzufügen, indem wir sie zuweisen:
nullProtoObj.toString = Object.prototype.toString; // since new object lacks toString, add the original generic one back
console.log(nullProtoObj.toString()); // shows "[object Object]"
console.log(`nullProtoObj is: ${nullProtoObj}`); // shows "nullProtoObj is: [object Object]"
Im Gegensatz zu normalen Objekten, bei denen toString()
im Prototyp des Objekts ist, ist die toString()
-Methode hier eine eigene Eigenschaft von nullProtoObj
. Dies liegt daran, dass nullProtoObj
keinen (null
) Prototyp hat.
Man kann ein null-Prototyp-Objekt auch in ein gewöhnliches Objekt zurückverwandeln, indem man Object.setPrototypeOf(nullProtoObj, Object.prototype)
aufruft.
In der Praxis werden Objekte mit null
Prototyp in der Regel als günstiger Ersatz für Maps verwendet. Das Vorhandensein von Object.prototype
-Eigenschaften kann einige Fehler verursachen:
const ages = { alice: 18, bob: 27 };
function hasPerson(name) {
return name in ages;
}
function getAge(name) {
return ages[name];
}
hasPerson("hasOwnProperty"); // true
getAge("toString"); // [Function: toString]
Die Verwendung eines null-Prototyp-Objekts beseitigt diese Gefahr, ohne zu viel Komplexität in die hasPerson
- und getAge
-Funktionen einzuführen:
const ages = Object.create(null, {
alice: { value: 18, enumerable: true },
bob: { value: 27, enumerable: true },
});
hasPerson("hasOwnProperty"); // false
getAge("toString"); // undefined
In solchen Fällen sollte die Hinzufügung von Methoden vorsichtig erfolgen, da sie mit den anderen als Daten gespeicherten Schlüssel-Wert-Paaren verwechselt werden können.
Das Verhindern, dass Ihr Objekt von Object.prototype
erbt, verhindert auch Angriffe durch Prototypverschmutzung. Wenn ein bösartiges Skript eine Eigenschaft zu Object.prototype
hinzufügt, ist sie auf jedem Objekt in Ihrem Programm zugänglich, außer bei Objekten, die einen null-Prototyp haben.
const user = {};
// A malicious script:
Object.prototype.authenticated = true;
// Unexpectedly allowing unauthenticated user to pass through
if (user.authenticated) {
// access confidential data
}
JavaScript hat auch integrierte APIs, die null
-Prototyp-Objekte erzeugen, insbesondere solche, die Objekte als Ad-hoc-Schlüssel-Wert-Sammlungen verwenden. Zum Beispiel:
- Der Rückgabewert von
Object.groupBy()
- Die
groups
- undindices.groups
-Eigenschaften des Ergebnisses vonRegExp.prototype.exec()
Array.prototype[Symbol.unscopables]
(alle[Symbol.unscopables]
-Objekte sollten einennull
-Prototyp haben)import.meta
- Modulnamespace-Objekte, die durch
import * as ns from "module";
oderimport()
erhalten werden
Der Begriff "null
-Prototyp-Objekt" umfasst oft auch jedes Objekt ohne Object.prototype
in seiner Prototypkette. Solche Objekte können mit extends null
erstellt werden, wenn man Klassen verwendet.
Objektumwandlung
Viele eingebaute Operationen, die Objekte erwarten, wandeln zuerst ihre Argumente in Objekte um. Die Operation lässt sich wie folgt zusammenfassen:
- Objekte werden unverändert zurückgegeben.
undefined
undnull
werfen einenTypeError
.- Primitiven wie
Number
,String
,Boolean
,Symbol
,BigInt
werden in ihre entsprechenden Objekt-Wrapper umgewandelt.
Es gibt zwei Möglichkeiten, nahezu denselben Effekt in JavaScript zu erzielen.
Object.prototype.valueOf()
:Object.prototype.valueOf.call(x)
führt genau die oben beschriebenen Objektumwandlungsschritte aus, umx
zu konvertieren.- Die
Object()
Funktion:Object(x)
verwendet denselben Algorithmus zur Konvertierung vonx
, außer dassundefined
undnull
keinenTypeError
werfen, sondern ein einfaches Objekt zurückgeben.
Stellen, die eine Objektumwandlung verwenden, umfassen:
- Das
object
-Parameter vonfor...in
-Schleifen. - Der
this
-Wert vonArray
-Methoden. - Parameter von
Object
-Methoden wieObject.keys()
. - Automatische Boxung, wenn auf einen Attribut auf einem primitiven Wert zugegriffen wird, da Primitive keine Eigenschaften haben.
- Der
this
-Wert beim Aufrufen einer nichtstrikten Funktion. Primitive werden verpackt, währendnull
undundefined
durch das globale Objekt ersetzt werden.
Im Gegensatz zur Konvertierung zu Primitiven ist der Objektumwandlungsprozess selbst in keiner Weise beobachtbar, da er keinen benutzerdefinierten Code wie toString
- oder valueOf
-Methoden aufruft.
Konstruktor
Object()
-
Wandelt die Eingabe in ein Objekt um.
Statische Methoden
Object.assign()
-
Kopiert die Werte aller aufzählbaren eigenen Eigenschaften von einem oder mehreren Quellobjekten in ein Zielobjekt.
Object.create()
-
Erstellt ein neues Objekt mit dem angegebenen Prototypobjekt und Eigenschaften.
Object.defineProperties()
-
Fügt einem Objekt die beschriebenen benannten Eigenschaften hinzu, die durch die gegebenen Deskriptoren beschrieben werden.
Object.defineProperty()
-
Fügt eine benannte Eigenschaft zu einem Objekt hinzu, die durch einen gegebenen Deskriptor beschrieben wird.
Object.entries()
-
Gibt ein Array zurück, das alle
[key, value]
-Paare der eigenen aufzählbaren String-Eigenschaften eines gegebenen Objekts enthält. Object.freeze()
-
Friert ein Objekt ein. Andere Codes können nicht die Eigenschaften löschen oder ändern.
Object.fromEntries()
-
Gibt ein neues Objekt aus einem iterierbaren Element von
[key, value]
-Paaren zurück. (Dies ist das Gegenteil vonObject.entries
). Object.getOwnPropertyDescriptor()
-
Gibt einen Eigenschaften-Deskriptor für eine benannte Eigenschaft eines Objekts zurück.
Object.getOwnPropertyDescriptors()
-
Gibt ein Objekt zurück, das alle eigenen Eigenschaften-Deskriptoren eines Objekts enthält.
Object.getOwnPropertyNames()
-
Gibt ein Array zurück, das die Namen aller eigenen aufzählbaren und nicht-auflistungsfähigen Eigenschaften eines gegebenen Objekts enthält.
Object.getOwnPropertySymbols()
-
Gibt ein Array aller direkt auf einem gegebenen Objekt gefundenen Symboleigenschaften zurück.
Object.getPrototypeOf()
-
Gibt den Prototyp (interne
[[Prototype]]
-Eigenschaft) des angegebenen Objekts zurück. Object.groupBy()
-
Gruppiert die Elemente eines gegebenen Iterators entsprechend den String-Werten, die von einer bereitgestellten Rückruffunktion zurückgegeben werden. Das zurückgegebene Objekt hat separate Eigenschaften für jede Gruppe, die Arrays mit den Elementen der Gruppe enthalten.
Object.hasOwn()
-
Gibt
true
zurück, wenn das angegebene Objekt die angegebene Eigenschaft als eigene Eigenschaft hat, oderfalse
, wenn die Eigenschaft geerbt ist oder nicht existiert. Object.is()
-
Vergleicht, ob zwei Werte derselbe Wert sind. Bewertet alle
NaN
-Werte als gleich (was sich sowohl vonIsLooselyEqual
, das von==
verwendet wird, als auch vonIsStrictlyEqual
, das von===
verwendet wird, unterscheidet). Object.isExtensible()
-
Bestimmt, ob die Erweiterung eines Objekts erlaubt ist.
Object.isFrozen()
-
Bestimmt, ob ein Objekt eingefroren wurde.
Object.isSealed()
-
Bestimmt, ob ein Objekt versiegelt ist.
Object.keys()
-
Gibt ein Array zurück, das die Namen aller eigenen aufzählbaren String-Eigenschaften eines gegebenen Objekts enthält.
Object.preventExtensions()
-
Verhindert Erweiterungen eines Objekts.
Object.seal()
-
Verhindert, dass andere Codes Eigenschaften eines Objekts löschen.
Object.setPrototypeOf()
-
Setzt den Prototyp des Objekts (seine interne
[[Prototype]]
-Eigenschaft) fest. Object.values()
-
Gibt ein Array zurück, das die Werte enthält, die allen eigenen aufzählbaren String-Eigenschaften eines gegebenen Objekts entsprechen.
Instanz-Eigenschaften
Diese Eigenschaften sind auf Object.prototype
definiert und werden von allen Object
-Instanzen gemeinsam genutzt.
Object.prototype.__proto__
Veraltet-
Zeigt auf das Objekt, das beim Instanziieren des Objekts als Prototyp verwendet wurde.
Object.prototype.constructor
-
Die Konstruktorfunktion, die das Instanzobjekt erstellt hat. Für einfache
Object
-Instanzen ist der anfängliche Wert derObject
-Konstruktor. Instanzen anderer Konstruktoren erben jeweils dieconstructor
-Eigenschaft von ihrem jeweiligenConstructor.prototype
-Objekt.
Instanz-Methoden
Object.prototype.__defineGetter__()
Veraltet-
Verknüpft eine Funktion mit einer Eigenschaft, die beim Zugriff ausgeführt wird und ihren Rückgabewert zurückgibt.
Object.prototype.__defineSetter__()
Veraltet-
Verknüpft eine Funktion mit einer Eigenschaft, die beim Festlegen ausgeführt wird und die Eigenschaft ändert.
Object.prototype.__lookupGetter__()
Veraltet-
Gibt die Funktion zurück, die als Getter an die angegebene Eigenschaft gebunden ist.
Object.prototype.__lookupSetter__()
Veraltet-
Gibt die Funktion zurück, die als Setter an die angegebene Eigenschaft gebunden ist.
Object.prototype.hasOwnProperty()
-
Gibt einen Booleschen Wert zurück, der angibt, ob ein Objekt die angegebene Eigenschaft als direkte Eigenschaft dieses Objekts enthält und nicht durch die Prototypkette geerbt wird.
Object.prototype.isPrototypeOf()
-
Gibt einen Booleschen Wert zurück, der angibt, ob das Objekt, auf das diese Methode aufgerufen wird, in der Prototypkette des angegebenen Objekts ist.
Object.prototype.propertyIsEnumerable()
-
Gibt einen Booleschen Wert zurück, der angibt, ob die angegebene Eigenschaft die aufzählbare eigene Eigenschaft des Objekts ist.
Object.prototype.toLocaleString()
-
Ruft
toString()
auf. Object.prototype.toString()
-
Gibt eine String-Repräsentation des Objekts zurück.
Object.prototype.valueOf()
-
Gibt den primitiven Wert des angegebenen Objekts zurück.
Beispiele
Erstellen leerer Objekte
Das folgende Beispiel erstellt leere Objekte mit dem new
-Schlüsselwort und verschiedenen Argumenten:
const o1 = new Object();
const o2 = new Object(undefined);
const o3 = new Object(null);
Verwenden des Objekt() Konstruktors, um Primitive in ein Objekt ihres jeweiligen Typs zu verwandeln
Sie können den Object()
-Konstruktor verwenden, um einen Objekt-Wrapper eines primitiven Werts zu erstellen.
Die folgenden Beispiele erstellen Variablen o1
und o2
, die Boolean
- und BigInt
-Werte speichern:
// Equivalent to const o1 = new Boolean(true)
const o1 = new Object(true);
// No equivalent because BigInt() can't be called as a constructor,
// and calling it as a regular function won't create an object
const o2 = new Object(1n);
Objektprototypen
Wenn Sie das Verhalten bestehender Object.prototype
-Methoden ändern, überlegen Sie, Code durch das Einfügen von Code vor oder nach der bestehenden Logik zu erweitern. Zum Beispiel wird dieses (ungetestete) Codebeispiel benutzerdefinierte Logik vor der eingebauten Logik oder einer Erweiterung eines anderen ausführen.
Wenn Sie Prototypen mit Hooks ändern, übergeben Sie this
und die Argumente (den Aufrufzustand) an das aktuelle Verhalten, indem Sie apply()
auf der Funktion aufrufen. Dieses Muster kann für jeden Prototyp verwendet werden, wie etwa Node.prototype
, Function.prototype
, etc.
const current = Object.prototype.valueOf;
// Since my property "-prop-value" is cross-cutting and isn't always
// on the same prototype chain, I want to modify Object.prototype:
Object.prototype.valueOf = function (...args) {
if (Object.hasOwn(this, "-prop-value")) {
return this["-prop-value"];
} else {
// It doesn't look like one of my objects, so let's fall back on
// the default behavior by reproducing the current behavior as best we can.
// The apply behaves like "super" in some other languages.
// Even though valueOf() doesn't take arguments, some other hook may.
return current.apply(this, args);
}
};
Warnung: Die Modifikation der prototype
-Eigenschaft eines beliebigen eingebauten Konstruktors wird als schlechte Praxis betrachtet und birgt Risiken für die Kompatibilität in der Zukunft.
Weitere Informationen über Prototypen finden Sie in Vererbung und die Prototypkette.
Spezifikationen
Specification |
---|
ECMAScript Language Specification # sec-object-objects |
Browser-Kompatibilität
BCD tables only load in the browser