[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty [Back]  [Original]

Object.defineProperty() - JavaScript | MDN

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.defineProperty()

Baseline Weitgehend verfgbar

Diese Funktion ist gut etabliert und funktioniert auf vielen Gerten und in vielen Browserversionen. Sie ist seit Juli 2015 browserbergreifend verfgbar.

Die Object.defineProperty() statische Methode definiert eine neue Eigenschaft direkt auf einem Objekt oder ndert eine bestehende Eigenschaft auf einem Objekt und gibt das Objekt zurck.

In diesem Artikel

Probieren Sie es aus

const object = {};

Object.defineProperty(object, "foo", {
  value: 42,
  writable: false,
});

object.foo = 77;
// Throws an error in strict mode

console.log(object.foo);
// Expected output: 42

Syntax

js
Object.defineProperty(obj, prop, descriptor)

Parameter

obj

Das Objekt, auf dem die Eigenschaft definiert werden soll.

prop

Ein String oder Symbol, der den Schlssel der zu definierenden oder zu ndernden Eigenschaft spezifiziert.

descriptor

Der Deskriptor fr die definierte oder genderte Eigenschaft.

Rckgabewert

Das der Funktion bergebene Objekt, bei dem die angegebene Eigenschaft hinzugefgt oder gendert wurde.

Beschreibung

Object.defineProperty() ermglicht eine przise Ergnzung oder nderung einer Eigenschaft auf einem Objekt. Die normale Eigenschaftszuweisung durch Zuweisung erstellt Eigenschaften, die bei der Eigenschaftsaufzhlung sichtbar sind (for...in, Object.keys(), etc.), deren Werte gendert werden knnen und die gelscht werden knnen. Diese Methode erlaubt es, diese zustzlichen Details von ihren Standardeinstellungen zu ndern. Standardmig sind Eigenschaften, die mit Object.defineProperty() hinzugefgt werden, nicht schreibbar, nicht aufzhlbar und nicht konfigurierbar. Darber hinaus verwendet Object.defineProperty() die interne Methode [[DefineOwnProperty]], anstatt [[Set]], sodass es keine Setter aufruft, selbst wenn die Eigenschaft bereits vorhanden ist.

Eigenschaftsdeskriptoren in Objekten gibt es in zwei Hauptarten: Daten-Deskriptoren und Accessor-Deskriptoren. Ein Daten-Deskriptor ist eine Eigenschaft mit einem Wert, der mglicherweise schreibbar ist oder nicht. Ein Accessor-Deskriptor ist eine Eigenschaft, die durch ein Getter-Setter-Paar von Funktionen beschrieben wird. Ein Deskriptor muss eine dieser beiden Arten sein; er kann nicht beides sein.

Sowohl Daten- als auch Accessor-Deskriptoren sind Objekte. Sie teilen sich die folgenden optionalen Schlssel (bitte beachten: die hier erwhnten Standardeinstellungen gelten bei der Definition von Eigenschaften mit Object.defineProperty()):

configurable

wenn dies auf false gesetzt ist,

  • kann der Typ dieser Eigenschaft nicht zwischen Daten- und Accessor-Eigenschaft gendert werden, und
  • die Eigenschaft kann nicht gelscht werden, und
  • andere Attribute seines Deskriptors knnen nicht gendert werden (jedoch, wenn es sich um einen Daten-Deskriptor mit writable: true handelt, kann der value gendert werden und writable kann auf false gendert werden).

Standard ist false.

enumerable

true nur dann, wenn diese Eigenschaft bei der Aufzhlung der Eigenschaften auf dem entsprechenden Objekt sichtbar wird. Standard ist false.

Ein Daten-Deskriptor hat auch die folgenden optionalen Schlssel:

value

Der mit der Eigenschaft verknpfte Wert. Kann jeder gltige JavaScript-Wert sein (Zahl, Objekt, Funktion, etc.). Standard ist undefined.

writable

true, wenn der mit der Eigenschaft verknpfte Wert mit einem Zuweisungsoperator gendert werden kann. Standard ist false.

Ein Accessor-Deskriptor hat auch die folgenden optionalen Schlssel:

get

Eine Funktion, die als Getter fr die Eigenschaft dient, oder undefined, wenn es keinen Getter gibt. Wenn auf die Eigenschaft zugegriffen wird, wird diese Funktion ohne Argumente und mit this auf das Objekt gesetzt, durch das die Eigenschaft angesprochen wird (dies muss nicht das Objekt sein, auf dem die Eigenschaft definiert ist, durch Vererbung). Der Rckgabewert wird als Wert der Eigenschaft verwendet. Standard ist undefined.

set

Eine Funktion, die als Setter fr die Eigenschaft dient, oder undefined, wenn es keinen Setter gibt. Wenn der Eigenschaft ein Wert zugewiesen wird, wird diese Funktion mit einem Argument (dem der Eigenschaft zugewiesenen Wert) und mit this auf das Objekt gesetzt, durch das die Eigenschaft zugewiesen wird, aufgerufen. Standard ist undefined.

Wenn ein Deskriptor keinen der value, writable, get und set Schlssel hat, wird er als Daten-Deskriptor behandelt. Wenn ein Deskriptor sowohl ein Daten-Deskriptor (weil er value oder writable hat) als auch ein Accessor-Deskriptor (weil er get oder set hat) ist, wird eine Ausnahme ausgelst.

Diese Attribute sind nicht zwangslufig die eigenen Eigenschaften des Deskriptors. Geerbte Eigenschaften werden ebenfalls bercksichtigt. Um sicherzustellen, dass diese Standardeinstellungen beibehalten werden, knnen Sie bestehende Objekte in der Prototypenkette des Deskriptorobjekts im Voraus einfrieren, alle Optionen explizit angeben oder ein null-Prototyp-Objekt erstellen.

js
const obj = {};
// 1. Using a null prototype: no inherited properties
const descriptor = Object.create(null);
descriptor.value = "static";

// not enumerable, not configurable, not writable as defaults
Object.defineProperty(obj, "key", descriptor);

// 2. Being explicit by using a throw-away object literal with all attributes present
Object.defineProperty(obj, "key2", {
  enumerable: false,
  configurable: false,
  writable: false,
  value: "static",
});

// 3. Prevents adding or removing the object prototype properties
// (value, get, set, enumerable, writable, configurable)
Object.freeze(Object.prototype);

Wenn die Eigenschaft bereits existiert, versucht Object.defineProperty(), die Eigenschaft gem den Werten im Deskriptor und der aktuellen Konfiguration der Eigenschaft zu ndern.

Wenn das alte Deskriptor seine configurable Eigenschaft auf false gesetzt hat, wird die Eigenschaft als nicht konfigurierbar bezeichnet. Es ist nicht mglich, irgendwelche Attribute einer nicht konfigurierbaren Accessor-Eigenschaft zu ndern, und es ist nicht mglich, zwischen Daten- und Accessor-Eigenschaftstypen zu wechseln. Fr Daten-Eigenschaften mit writable: true ist es mglich, den Wert zu ndern und das writable Attribut von true auf false zu ndern. Ein TypeError wird ausgelst, wenn versucht wird, nicht konfigurierbare Eigenschaftenattribute zu ndern (auer value und writable, falls erlaubt), auer wenn ein Wert definiert wird, der derselbe wie der ursprngliche Wert auf einer Daten-Eigenschaft ist.

Wenn die aktuelle Eigenschaft konfigurierbar ist, lscht die Definition eines Attributs auf undefined effektiv das Attribut. Zum Beispiel, wenn o.k eine Accessor-Eigenschaft ist, entfernt Object.defineProperty(o, "k", { set: undefined }) den Setter, wodurch k nur einen Getter hat und somit schreibgeschtzt wird. Wenn ein Attribut im neuen Deskriptor fehlt, behlt es den Wert des alten Deskriptor-Attributs (es wird nicht implizit auf undefined zurckgesetzt). Es ist mglich, zwischen Daten- und Accessor-Eigenschaften zu wechseln, indem man einen Deskriptor eines anderen "Typs" angibt. Zum Beispiel, wenn der neue Deskriptor ein Daten-Deskriptor ist (mit value oder writable), werden die get und set Attribute des ursprnglichen Deskriptors beide entfernt.

Beispiele

Erstellen einer Eigenschaft

Wenn die angegebene Eigenschaft im Objekt nicht existiert, erstellt Object.defineProperty() eine neue Eigenschaft wie beschrieben. Felder knnen im Deskriptor weggelassen werden und Standardwerte fr diese Felder werden eingefgt.

js
const o = {}; // Creates a new object

// Example of an object property added
// with defineProperty with a data property descriptor
Object.defineProperty(o, "a", {
  value: 37,
  writable: true,
  enumerable: true,
  configurable: true,
});
// 'a' property exists in the o object and its value is 37

// Example of an object property added
// with defineProperty with an accessor property descriptor
let bValue = 38;
Object.defineProperty(o, "b", {
  get() {
    return bValue;
  },
  set(newValue) {
    bValue = newValue;
  },
  enumerable: true,
  configurable: true,
});
o.b; // 38
// 'b' property exists in the o object and its value is 38
// The value of o.b is now always identical to bValue,
// unless o.b is redefined

// You cannot try to mix both:
Object.defineProperty(o, "conflict", {
  value: 0x9f91102,
  get() {
    return 0xdeadbeef;
  },
});
// throws a TypeError: value appears
// only in data descriptors,
// get appears only in accessor descriptors

ndern einer Eigenschaft

Beim ndern einer vorhandenen Eigenschaft bestimmt die aktuelle Eigenschaftskonfiguration, ob der Operator erfolgreich ist, nichts tut oder einen TypeError auslst.

Schreibbares Attribut

Wenn das writable Eigenschaftsattribut false ist, wird die Eigenschaft als "nicht-schreibbar" bezeichnet. Sie kann nicht neu zugewiesen werden. Der Versuch, einer nicht-schreibbaren Eigenschaft einen neuen Wert zuzuweisen, ndert sie nicht und fhrt zu einem Fehler im striktem Modus.

js
const o = {}; // Creates a new object

Object.defineProperty(o, "a", {
  value: 37,
  writable: false,
});

console.log(o.a); // 37
o.a = 25; // No error thrown
// (it would throw in strict mode,
// even if the value had been the same)
console.log(o.a); // 37; the assignment didn't work

// strict mode
(() => {
  "use strict";
  const o = {};
  Object.defineProperty(o, "b", {
    value: 2,
    writable: false,
  });
  o.b = 3; // throws TypeError: "b" is read-only
  return o.b; // returns 2 without the line above
})();

Aufzhlbares Attribut

Das enumerable Eigenschaftsattribut definiert, ob die Eigenschaft von Object.assign() oder dem Spread Operator bercksichtigt wird. Fr nicht-Symbol Eigenschaften definiert es auch, ob sie in einer for...in Schleife und Object.keys() angezeigt werden oder nicht. Fr weitere Informationen siehe Aufzhlbarkeit und Eigentum von Eigenschaften.

js
const o = {};
Object.defineProperty(o, "a", {
  value: 1,
  enumerable: true,
});
Object.defineProperty(o, "b", {
  value: 2,
  enumerable: false,
});
Object.defineProperty(o, "c", {
  value: 3,
}); // enumerable defaults to false
o.d = 4; // enumerable defaults to true when creating a property by setting it
Object.defineProperty(o, Symbol.for("e"), {
  value: 5,
  enumerable: true,
});
Object.defineProperty(o, Symbol.for("f"), {
  value: 6,
  enumerable: false,
});

for (const i in o) {
  console.log(i);
}
// Logs 'a' and 'd' (always in that order)

Object.keys(o); // ['a', 'd']

o.propertyIsEnumerable("a"); // true
o.propertyIsEnumerable("b"); // false
o.propertyIsEnumerable("c"); // false
o.propertyIsEnumerable("d"); // true
o.propertyIsEnumerable(Symbol.for("e")); // true
o.propertyIsEnumerable(Symbol.for("f")); // false

const p = { ...o };
p.a; // 1
p.b; // undefined
p.c; // undefined
p.d; // 4
p[Symbol.for("e")]; // 5
p[Symbol.for("f")]; // undefined

Konfigurierbares Attribut

Das configurable Attribut steuert, ob die Eigenschaft aus dem Objekt gelscht werden kann und ob ihre Attribute (auer value und writable) gendert werden knnen.

Dieses Beispiel zeigt eine nicht konfigurierbare Accessor-Eigenschaft.

js
const o = {};
Object.defineProperty(o, "a", {
  get() {
    return 1;
  },
  configurable: false,
});

Object.defineProperty(o, "a", {
  configurable: true,
}); // throws a TypeError
Object.defineProperty(o, "a", {
  enumerable: true,
}); // throws a TypeError
Object.defineProperty(o, "a", {
  set() {},
}); // throws a TypeError (set was undefined previously)
Object.defineProperty(o, "a", {
  get() {
    return 1;
  },
}); // throws a TypeError
// (even though the new get does exactly the same thing)
Object.defineProperty(o, "a", {
  value: 12,
}); // throws a TypeError
// ('value' can be changed when 'configurable' is false, but only when the property is a writable data property)

console.log(o.a); // 1
delete o.a; // Nothing happens; throws an error in strict mode
console.log(o.a); // 1

Wenn das configurable Attribut von o.a true gewesen wre, wrden keine Fehler ausgelst werden und die Eigenschaft wrde am Ende gelscht werden.

Dieses Beispiel zeigt eine nicht konfigurierbare aber schreibbare Daten-Eigenschaft. Der value der Eigenschaft kann immer noch gendert werden, und writable kann immer noch von true auf false umgeschaltet werden.

js
const o = {};
Object.defineProperty(o, "b", {
  writable: true,
  configurable: false,
});
console.log(o.b); // undefined
Object.defineProperty(o, "b", {
  value: 1,
}); // Even when configurable is false, because the object is writable, we may still replace the value
console.log(o.b); // 1
o.b = 2; // We can change the value with assignment operators as well
console.log(o.b); // 2
// Toggle the property's writability
Object.defineProperty(o, "b", {
  writable: false,
});
Object.defineProperty(o, "b", {
  value: 1,
}); // TypeError: because the property is neither writable nor configurable, it cannot be modified
// At this point, there's no way to further modify 'b'
// or restore its writability

Dieses Beispiel zeigt eine konfigurierbare, aber nicht schreibbare Daten-Eigenschaft. Der value der Eigenschaft kann immer noch mit defineProperty ersetzt werden (aber nicht mit Zuweisungsoperatoren), und writable kann umgeschaltet werden.

js
const o = {};
Object.defineProperty(o, "b", {
  writable: false,
  configurable: true,
});
Object.defineProperty(o, "b", {
  value: 1,
}); // We can replace the value with defineProperty
console.log(o.b); // 1
o.b = 2; // throws TypeError in strict mode: cannot change a non-writable property's value with assignment

Dieses Beispiel zeigt eine nicht konfigurierbare und nicht schreibbare Daten-Eigenschaft. Es gibt keine Mglichkeit, irgendein Attribut der Eigenschaft zu aktualisieren, einschlielich ihres value.

js
const o = {};
Object.defineProperty(o, "b", {
  writable: false,
  configurable: false,
});
Object.defineProperty(o, "b", {
  value: 1,
}); // TypeError: the property cannot be modified because it is neither writable nor configurable.

Hinzufgen von Eigenschaften und Standardeinstellungen

Es ist wichtig, die Art und Weise zu bercksichtigen, wie Standardwerte von Attributen angewendet werden. Es gibt oft einen Unterschied zwischen der Verwendung von Eigenschafts-Accessoren zur Zuweisung eines Wertes und der Verwendung von Object.defineProperty(), wie im folgenden Beispiel gezeigt.

js
const o = {};

o.a = 1;
// is equivalent to:
Object.defineProperty(o, "a", {
  value: 1,
  writable: true,
  configurable: true,
  enumerable: true,
});

// On the other hand,
Object.defineProperty(o, "a", { value: 1 });
// is equivalent to:
Object.defineProperty(o, "a", {
  value: 1,
  writable: false,
  configurable: false,
  enumerable: false,
});

Benutzerdefinierte Setter und Getter

Das folgende Beispiel zeigt, wie ein sich selbst archivierendes Objekt implementiert werden kann. Wenn die temperature Eigenschaft gesetzt wird, erhlt das archive Array einen Protokolleintrag.

js
function Archiver() {
  let temperature = null;
  const archive = [];

  Object.defineProperty(this, "temperature", {
    get() {
      console.log("get!");
      return temperature;
    },
    set(value) {
      temperature = value;
      archive.push({ val: temperature });
    },
  });

  this.getArchive = () => archive;
}

const arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]

In diesem Beispiel gibt ein Getter immer denselben Wert zurck.

js
const pattern = {
  get() {
    return "I always return this string, whatever you have assigned";
  },
  set() {
    this.myName = "this is my name string";
  },
};

function TestDefineSetAndGet() {
  Object.defineProperty(this, "myProperty", pattern);
}

const instance = new TestDefineSetAndGet();
instance.myProperty = "test";
console.log(instance.myProperty);
// I always return this string, whatever you have assigned

console.log(instance.myName); // this is my name string

Vererbung von Eigenschaften

Wenn eine Accessor-Eigenschaft vererbt wird, werden ihre get und set Methoden aufgerufen, wenn die Eigenschaft in Nachkommenobjekten angesprochen oder gendert wird. Wenn diese Methoden eine Variable verwenden, um den Wert zu speichern, wird dieser Wert von allen Objekten geteilt.

js
function MyClass() {}

let value;
Object.defineProperty(MyClass.prototype, "x", {
  get() {
    return value;
  },
  set(x) {
    value = x;
  },
});

const a = new MyClass();
const b = new MyClass();
a.x = 1;
console.log(b.x); // 1

Dies kann behoben werden, indem der Wert in einer anderen Eigenschaft gespeichert wird. In get und set Methoden zeigt this auf das Objekt, das verwendet wird, um die Eigenschaft anzusprechen oder zu ndern.

js
function MyClass() {}

Object.defineProperty(MyClass.prototype, "x", {
  get() {
    return this.storedX;
  },
  set(x) {
    this.storedX = x;
  },
});

const a = new MyClass();
const b = new MyClass();
a.x = 1;
console.log(b.x); // undefined

Im Gegensatz zu Accessor-Eigenschaften werden Daten-Eigenschaften immer auf dem Objekt selbst und nicht auf einem Prototyp gesetzt. Wenn jedoch eine nicht schreibbare Daten-Eigenschaft vererbt wird, wird immer noch verhindert, dass sie auf dem Objekt gendert wird.

js
function MyClass() {}

MyClass.prototype.x = 1;
Object.defineProperty(MyClass.prototype, "y", {
  writable: false,
  value: 1,
});

const a = new MyClass();
a.x = 2;
console.log(a.x); // 2
console.log(MyClass.prototype.x); // 1
a.y = 2; // Ignored, throws in strict mode
console.log(a.y); // 1
console.log(MyClass.prototype.y); // 1

Spezifikationen

Spezifikation
ECMAScript 2027 LanguageSpecification
# sec-object.defineproperty

Browser-Kompatibilitt

Siehe auch


Web Proxy Viewer  |  New URL  |  Original Page