Object
Baseline
Weitgehend verfügbar
*
Diese Funktion ist gut etabliert und funktioniert auf vielen Geräten und in vielen Browserversionen. Sie ist seit Juli 2015 browserübergreifend verfügbar.
* Einige Teile dieser Funktion werden möglicherweise unterschiedlich gut unterstützt.
Der Object-Typ repräsentiert einen der JavaScripts Datentypen. Er wird verwendet, um verschiedene schlüsselbasierte Sammlungen und komplexere Entitäten zu speichern. Objekte können entweder mit dem Object()-Konstruktor oder der Objektinitialisierer-/Literal-Syntax erstellt werden.
Beschreibung
Fast alle Objekte in JavaScript sind Instanzen von Object; ein typisches Objekt erbt Eigenschaften (einschließlich Methoden) von Object.prototype, auch wenn diese Eigenschaften überschattet (d.h. überschrieben) werden können. Die einzigen Objekte, die nicht von Object.prototype erben, sind Objekte mit null-Prototyp oder solche, die von anderen null-Prototypobjekten abgeleitet sind.
Änderungen am Object.prototype-Objekt sind durch die Prototypkette für alle Objekte sichtbar, es sei denn, die Eigenschaften und Methoden, die diesen Änderungen unterliegen, werden weiter unten in der Prototypkette überschrieben. Dies bietet eine sehr mächtige, jedoch potenziell gefährliche Mechanismus, um 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, das einen unveränderlichen Prototyp hat – der Prototyp von Object.prototype ist immer null und nicht änderbar.
Eigenschaften des Objektprototyps
Sie sollten es vermeiden, Methoden von Object.prototype direkt von der Instanz aus aufzurufen, insbesondere jene, die nicht polymorph sein sollen (d.h. bei denen nur das ursprüngliche Verhalten sinnvoll ist und kein abgeleitetes Objekt es sinnvoll überschreiben könnte). Alle von Object.prototype abstammenden Objekte können eine eigene benutzerdefinierte Eigenschaft mit demselben Namen definieren, die jedoch völlig andere Semantiken bietet, als Sie erwarten. Außerdem werden diese Eigenschaften nicht von null-Prototypobjekten geerbt. Alle modernen JavaScript-Dienstprogramme für die Arbeit mit Objekten sind statisch. Konkret:
valueOf(),toString()undtoLocaleString()existieren, um polymorph zu sein, und Sie sollten erwarten, dass das Objekt seine eigene Implementierung mit sinnvollen Verhaltensweisen definiert, sodass Sie sie als Instanzmethoden aufrufen können.valueOf()undtoString()werden in der Regel jedoch implizit durch Typkonvertierung aufgerufen, und Sie müssen sie nicht selbst in Ihrem Code aufrufen.__defineGetter__(),__defineSetter__(),__lookupGetter__()und__lookupSetter__()sind veraltet und sollten nicht mehr 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()undObject.hasOwn()ersetzt werden. - Die Methode
isPrototypeOf()kann normalerweise mitinstanceofersetzt werden, wenn Sie dieprototype-Eigenschaft eines Konstruktors überprüfen.
Falls es keine semantisch äquivalente statische Methode gibt oder wenn Sie wirklich die Object.prototype-Methode verwenden möchten, sollten Sie die Object.prototype-Methode direkt mit call() auf Ihrem Zielobjekt aufrufen, um zu verhindern, dass das Objekt eine überschreibende Eigenschaft hat, die unerwartete Ergebnisse liefert.
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 Objekt selbst, um seine eigenen Eigenschaften zu löschen (wie z. B. Map.prototype.delete()). Um dies zu tun, muss man den delete-Operator verwenden.
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 Objektinitialisierer-Syntax mit __proto__: null erstellen (beachten Sie: Der Schlüssel __proto__ in Objektliteralen unterscheidet sich von der veralteten Object.prototype.__proto__-Eigenschaft). Sie können auch den Prototyp eines bestehenden Objekts auf null setzen, indem Sie Object.setPrototypeOf(obj, null) aufrufen.
const obj = Object.create(null);
const obj2 = { __proto__: null };
Ein Objekt mit einem null-Prototyp kann sich auf unerwartete Weise verhalten, da es keine Objektmethoden von Object.prototype erbt. Dies gilt insbesondere beim Debuggen, da gängige Werkzeuge zur Objekt-Eigenschaftskonvertierung/-erkennung Fehler erzeugen oder Informationen verlieren können (besonders wenn stille Fehlerschutzmaßnahmen verwendet werden, 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 scheitern.
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 zurück zu dem Null-Prototypobjekt hinzufügen, indem wir ihm eine 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. Das liegt daran, dass nullProtoObj keinen (null) Prototyp hat.
Sie können auch ein Null-Prototypobjekt zurück in ein gewöhnliches Objekt umwandeln, indem Sie Object.setPrototypeOf(nullProtoObj, Object.prototype) aufrufen.
In der Praxis werden Objekte mit null-Prototyp oft als günstiger Ersatz für Maps verwendet. Die Anwesenheit 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]
Das Verwenden eines Null-Prototypobjekts 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 einem solchen Fall sollte das Hinzufügen von Methoden vorsichtig erfolgen, da sie mit den anderen als Daten gespeicherten Schlüssel-Werte-Paaren verwechselt werden können.
Wenn Ihr Objekt nicht von Object.prototype erbt, verhindert es auch Prototype Pollution-Angriffe. Wenn ein bösartiges Skript eine Eigenschaft zu Object.prototype hinzufügt, wird sie auf jedem Objekt in Ihrem Programm zugänglich sein, außer auf 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 eingebaute APIs, die null-Prototypobjekte 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 einen Null-Prototyp haben)import.meta- Modul-Namespace-Objekte, die durch
import * as ns from "module";oderimport()erhalten werden
Der Begriff "null-Prototypobjekt" schließt oft auch alle Objekte ohne Object.prototype in ihrer Prototypkette ein. Solche Objekte können mit extends null erstellt werden, wenn Klassen verwendet werden.
Objektkoerzierung
Viele eingebaute Operationen, die Objekte erwarten, erzwingen zuerst, dass ihre Argumente zu Objekten umgewandelt werden. Der Vorgang kann wie folgt zusammengefasst werden:
- Objekte werden unverändert zurückgegeben.
undefinedundnullwerfen einTypeError.Number,String,Boolean,Symbol,BigIntPrimitive werden in ihre entsprechenden Objektumhüllungen gewickelt.
Es gibt zwei Möglichkeiten, fast denselben Effekt in JavaScript zu erzielen.
Object.prototype.valueOf():Object.prototype.valueOf.call(x)führt genau die oben erklärten Objektkoerzierungsschritte aus, umxzu konvertieren.- Die
Object()-Funktion:Object(x)verwendet denselben Algorithmus, umxzu konvertieren, mit der Ausnahme, dassundefinedundnullkeinenTypeErrorwerfen, sondern ein einfaches Objekt zurückgeben.
Plätze, die Objektkoerzierung verwenden, sind:
- Der
object-Parameter vonfor...inSchleifen. - Der
this-Wert vonArray-Methoden. - Parameter von
Object-Methoden wieObject.keys(). - Automatische Boxen, wenn auf einen primitiven Wert zugegriffen wird, da Primitive keine Eigenschaften haben.
- Der
this-Wert beim Aufrufen einer nicht-strikten Funktion. Primitive werden in einer Box verpackt, währendnullundundefineddurch das Globale Objekt ersetzt werden.
Im Gegensatz zur Konvertierung zu Primitive ist der Koerzierungsvorgang selbst in keiner Weise beobachtbar, da er keinen benutzerdefinierten Code wie toString- oder valueOf-Methoden aufruft.
Konstruktor
Object()-
Konvertiert die Eingabe in ein Objekt.
Statische Methoden
Object.assign()-
Kopiert die Werte aller eigenen aufzählbaren Eigenschaften von einem oder mehreren Quellobjekten auf ein Zielobjekt.
Object.create()-
Erstellt ein neues Objekt mit dem angegebenen Prototyp-Objekt und Eigenschaften.
Object.defineProperties()-
Fügt die in den gegebenen Deskriptoren beschriebenen benannten Eigenschaften zu einem Objekt hinzu.
Object.defineProperty()-
Fügt die in einem gegebenen Deskriptor beschriebene benannte Eigenschaft zu einem Objekt hinzu.
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. Anderer Code kann seine Eigenschaften nicht löschen oder ändern.
Object.fromEntries()-
Gibt ein neues Objekt aus einem iterierbaren Objekt von
[Key, Value]-Paaren zurück. (Dies ist das Gegenteil vonObject.entries). Object.getOwnPropertyDescriptor()-
Gibt einen Eigenschaftsdeskriptor für eine benannte Eigenschaft eines Objekts zurück.
Object.getOwnPropertyDescriptors()-
Gibt ein Objekt zurück, das alle eigenen Eigenschaftsdeskriptoren für ein Objekt enthält.
Object.getOwnPropertyNames()-
Gibt ein Array zurück, das die Namen aller eigenen aufzählbaren und nicht aufzählbaren Eigenschaften des gegebenen Objekts enthält.
Object.getOwnPropertySymbols()-
Gibt ein Array aller unmittelbar auf einem gegebenen Objekt gefundenen Symbol-Eigenschaften zurück.
Object.getPrototypeOf()-
Gibt den Prototyp (interne
[[Prototyp]]-Eigenschaft) des angegebenen Objekts zurück. Object.groupBy()-
Gruppiert die Elemente eines gegebenen iterierbaren Objekts nach den von einer bereitgestellten Rückruffunktion zurückgegebenen String-Werten. Das zurückgegebene Objekt hat separate Eigenschaften für jede Gruppe, die Arrays mit den Elementen in der Gruppe enthalten.
Object.hasOwn()-
Gibt
truezurück, wenn das angegebene Objekt die angegebene Eigenschaft als eigene Eigenschaft besitzt, oderfalse, wenn die Eigenschaft geerbt ist oder nicht existiert. Object.is()-
Vergleicht, ob zwei Werte derselbe Wert sind. Sammelt alle
NaN-Werte (was sich sowohl vomIsLooselyEqualbeim==als auch vomIsStrictlyEqualbeim===unterscheidet). Object.isExtensible()-
Bestimmt, ob eine Erweiterung eines Objekts zugelassen 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 des gegebenen Objekts enthält.
Object.preventExtensions()-
Verhindert alle Erweiterungen eines Objekts.
Object.seal()-
Verhindert, dass anderer Code Eigenschaften eines Objekts löscht.
Object.setPrototypeOf()-
Setzt den Prototyp des Objekts (seine interne
[[Prototype]]-Eigenschaft). Object.values()-
Gibt ein Array zurück, das die Werte enthält, die den eigenen aufzählbaren String-Eigenschaften eines gegebenen Objekts entsprechen.
Instanzeigenschaften
Diese Eigenschaften sind auf Object.prototype definiert und werden von allen Object-Instanzen geteilt.
Object.prototype.__proto__-
Verweist auf das Objekt, das als Prototyp verwendet wurde, als das Objekt instanziiert wurde.
Object.prototype.constructor-
Die Konstruktorfunktion, die das Instanzobjekt erzeugte. Für einfache
Object-Instanzen ist der Anfangswert derObject-Konstruktor. Instanzen anderer Konstruktoren erben jeweils dieconstructor-Eigenschaft von ihrem jeweiligenConstructor.prototype-Objekt.
Instanzmethoden
Object.prototype.__defineGetter__()-
Verknüpft eine Funktion mit einer Eigenschaft, die beim Zugriff auf die Funktion ausgeführt wird und ihren Rückgabewert zurückgibt.
Object.prototype.__defineSetter__()-
Verknüpft eine Funktion mit einer Eigenschaft, die beim Setzen ausgeführt wird und die Eigenschaft verändert.
Object.prototype.__lookupGetter__()-
Gibt die als Getter an die angegebene Eigenschaft gebundene Funktion zurück.
Object.prototype.__lookupSetter__()-
Gibt die als Setter an die angegebene Eigenschaft gebundene Funktion zurück.
Object.prototype.hasOwnProperty()-
Gibt einen booleschen Wert zurück, der angibt, ob ein Objekt die angegebene Eigenschaft als direkte Eigenschaft dieses Objekts und nicht durch die Prototypkette vererbt enthält.
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-Darstellung des Objekts zurück.
Object.prototype.valueOf()-
Gibt den primitiven Wert des angegebenen Objekts zurück.
Beispiele
>Leere Objekte konstruieren
Das folgende Beispiel erstellt leere Objekte mithilfe des new-Schlüsselworts mit unterschiedlichen Argumenten:
const o1 = new Object();
const o2 = new Object(undefined);
const o3 = new Object(null);
Den Object()-Konstruktor verwenden, um Primitive in ein Objekt ihres entsprechenden Typs zu verwandeln
Sie können den Object()-Konstruktor verwenden, um ein Objekt-Wrapper eines primitiven Werts zu erstellen.
Die folgenden Beispiele erstellen die Variablen o1 und o2, welche Objekte sind, 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 vorhandener Object.prototype-Methoden ändern, ziehen Sie in Betracht, Code einzufügen, indem Sie Ihre Erweiterung vor oder nach der vorhandenen Logik einwickeln. Zum Beispiel wird dieser (nicht getestete) Code benutzerdefinierte Logik vor der eingebauten Logik oder der Erweiterung eines anderen bedingt ausführen.
Wenn Sie Prototypen mit Hooks modifizieren, übergeben Sie this und die Argumente (den Aufrufzustand) an das aktuelle Verhalten, indem Sie apply() auf die Funktion aufrufen. Dieses Muster kann für jeden Prototyp verwendet werden, wie Node.prototype, Function.prototype usw.
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"];
}
// 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:
Das Ändern der prototype-Eigenschaft eines eingebauten Konstruktors wird als schlechte Praxis angesehen und birgt Risiken der zukünftigen Kompatibilität.
Sie können mehr über Prototypen in Vererbung und die Prototypkette lesen.
Spezifikationen
| Spezifikation |
|---|
| ECMAScript® 2027 Language Specification> # sec-object-objects> |