Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

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:

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.

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

js
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:

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

js
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:

js
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:

js
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:

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

js
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: