Property-Deskriptoren

Der Großteil Ihrer Interaktion mit Objekteigenschaften wird auf Oberflächenebene, u. a. durch Erstellen von Objektliteralen, Festlegen und Zugriff Property-Werten mithilfe von Schlüsseln festlegen. Sie können jedoch intern jedes Attribut von ein Objekt, mit dem Sie genau steuern können, wie auf diese Eigenschaften zugegriffen wird, verändert und definiert. Jede Objekteigenschaft verfügt über eine Reihe unsichtbarer Attribute. die Metadaten enthalten, die mit dieser Property verknüpft sind, die als „Property“ bezeichnet wird. Beschreibungen“.

Es gibt zwei Arten von Deskriptoren, die mit einer Eigenschaft verknüpft sind: Datendeskriptoren und Zugriffsdeskriptoren Ein Datendeskriptor enthält Schlüssel/Wert-Paare, die den Wert einer Eigenschaft enthalten, unabhängig davon, ob dieser value ist beschreibbar, konfigurierbar oder aufzählbar. Beschreibungen der Zugriffsfunktion enthalten Funktionen, die ausgeführt werden, wenn eine Eigenschaft festgelegt, geändert oder aufgerufen wird.

Attribut Deskriptortyp Standardwert aus
Object.defineProperty()
Beschreibung
[[Value]] Daten undefined Enthält den Wert einer Eigenschaft.
[[Writable]] Daten false Bestimmt, ob Sie den Wert der Eigenschaft ändern können.
[[Get]] Accessor undefined Die getter-Funktion der Eigenschaft, die ausgeführt wird, wenn der auf die Property zugegriffen wird.
[[Set]] Accessor undefined Die setter-Funktion des Attributs, die ausgeführt wird, wenn der festgelegt oder geändert wird.
[[Configurable]] Beides false Wenn dies false ist, kann die Property nicht gelöscht werden und Attribute nicht geändert werden. Wenn dies false ist und [[Writable]] gleich true ist, kann der Wert des Attributs immer noch geändert werden.
[[Enumerable]] Beides false Bei true können Sie über das Attribut iterieren: for...in-Schleifen oder die statische Object.keys() .

Für jedes dieser Attribute wird dieselbe Abkürzung wie [[Prototype]] verwendet, was bedeutet, dass ein direkter Zugriff auf diese Eigenschaften nicht vorgesehen ist. Verwenden Sie stattdessen die Methode Statische Methode Object.defineProperty() zum Definieren oder Ändern der Attribute einer -Objekt enthält. Object.defineProperty() akzeptiert drei Argumente: das zu bearbeitende Objekt, den zu erstellenden oder zu ändernden Eigenschaftsschlüssel und ein Objekt, das die Beschreibungen, die mit der Eigenschaft verknüpft sind, die erstellt oder geändert wird.

Standardmäßig werden mit Object.defineProperty() erstellte Properties nicht beschreibbar, aufzählbar oder konfigurierbar sind. Alle von Ihnen erstellten Properties entweder als Teil des Objektliterals oder unter Verwendung der Punkt- oder Klammerschreibweise beschreibbar, aufzählbar und konfigurierbar.

const myObj = {};

Object.defineProperty(myObj, 'myProperty', {
  value
: true,
  writable
: false
});

myObj
.myProperty;
> true

myObj
.myProperty = false;

myObj
.myProperty;
> true

Beispiel: Wenn [[Writable]] einen false-Wert hat und versucht wird, einen neuen Wert festzulegen für die verknüpfte Property schlägt außerhalb des strikten Modus unbemerkt fehl. In diesem Fall wird ein Fehler im strikten Modus:

{
   
const myObj = {};

   
Object.defineProperty(myObj, 'myProperty', {
    value
: true,
    writable
: false
   
});

    myObj
.myProperty = false;
    myObj
.myProperty;
}
> true

(function () {
   
"use strict";
   
const myObj = {};

   
Object.defineProperty(myObj, 'myProperty', {
    value
: true,
    writable
: false
   
});

    myObj
.myProperty = false;
    myObj
.myProperty;
}());\
> Uncaught TypeError: "myProperty" is read-only

Der effektive Einsatz von Deskriptoren ist ein recht fortgeschrittenes Konzept, aber die innere Struktur eines Objekts zu verstehen, Syntaxen für die gängigere Arbeit mit Objekten. Beispiel: Diese Konzepte kommen bei Verwendung der statischen Methode Object.create() zum Tragen, mit der Sie alle Prototypen, die mit der neuen Version verknüpft sind, -Objekt enthält.

Mit Object.create() wird ein neues Objekt erstellt. Dabei wird ein vorhandenes Objekt als Prototyp erstellen. Dadurch kann das neue Objekt Eigenschaften und Methoden von einem anderen eines benutzerdefinierten Objekts auf die gleiche Weise, wie Objekte Der in JavaScript integrierte Object-Prototyp. Wenn Sie Object.create() mit ein -Objekt als Argument enthält, wird ein leeres Objekt erstellt, wobei das übergebene Objekt als für ihren Prototyp.

const myCustomPrototype = {
 
'myInheritedProp': 10
};

const newObject = Object.create( myCustomPrototype );

newObject
;
> Object {  }
<prototype>: Object { myInheritedProp: 10 }
  myInheritedProp
: 10
 
<prototype>: Object { }

Object.create kann ein zweites Argument verwenden und eigene Attribute für die Neu erstelltes Objekt mit einer Syntax wie Object.defineProperty(): d. h. ein Objekt, das Schlüssel einer Reihe von Deskriptorattributen zuordnet:

const myCustomPrototype = {
 
'myInheritedProp': 10
};

const myObj = Object.create( myCustomPrototype, {
        myProperty
: {
            value
: "The new property value.",
            writable
: true,
            configurable
: true
       
}
 
});

myObj
;
> Object { }
    myProperty
: "The new property value."
   
<prototype>: Object { myInheritedProp: 10 }

In diesem Beispiel verwendet das neue Objekt (myObj) ein Objektliteral (myCustomPrototype) als Prototyp, der selbst die übernommenen Object.prototype, was zu einer Reihe übernommener Prototypen namens Prototypkette. Jedes Objekt hat einen Prototyp, ob zugewiesen oder übernommen. die über einen eigenen zugewiesenen oder übernommenen Prototyp verfügen. Diese Kette endet in null-Prototyp erstellt, für den es keinen eigenen Prototyp gibt.

const myPrototype = {
 
'protoProp': 10
};

const newObject = Object.setPrototypeOf( { 'objProp' : true }, myPrototype );

newObject
;
> Object { objProp: true }
    objProp
: true
   
<prototype>: Object { protoProp: 10 }
        protoProp
: 10
       
<prototype>: Object { }

Die im Prototyp eines Werts enthaltenen Eigenschaften sind auf der „obersten Ebene“ verfügbar. eines -Objekts, ohne direkt auf die Eigenschaft „Prototype“ zugreifen zu müssen:

const objectLiteral = {
   
"value" : true
};

objectLiteral
;
> Object { value: true }
    value
: true
   
<prototype>: Object { }

objectLiteral
.toString();
"[object Object]"

Dieses Muster gilt für die gesamte Prototypkette, -Objekt: Der Interpreter sucht beim Zugriff auf eine Eigenschaft danach Property auf jeder „Ebene“ der Prototypkette von oben nach unten bis findet die Eigenschaft oder die Kette endet:

const myCustomPrototype = {
 
'protoProp': "Prototype property value."
};

const myObj = Object.create( myCustomPrototype, {
    myProperty
: {
        value
: "Top-level property value.",
        writable
: true,
        configurable
: true
   
}
});

myObj
.protoProp;
> "Prototype property value."

Wissen testen

Welche Deskriptoren sind Accessors?

[[Get]]
[[Writable]]
[[Set]]