Większość interakcji z właściwościami obiektu na poziomie gruntu, w tym do tworzenia literałów obiektów oraz ustawiania i uzyskiwania dostępu za pomocą kluczy. Można jednak wewnętrznie skonfigurować dowolną właściwość obiekt zapewniający szczegółową kontrolę nad sposobem dostępu do tych właściwości, zmienić i zdefiniować. Każda właściwość obiektu ma zestaw niewidocznych atrybutów zawierające metadane powiązane z tą usługą o nazwie „property” deskryptory”.
Z każdą usługą powiązane są 2 typy deskryptorów: deskryptory danych i deskryptory akcesorów. Deskryptor danych zawiera par klucz-wartość, które zawierają wartość właściwości, niezależnie od tego, czy można zapisywać, konfigurować lub wyliczać. Deskryptory akcesorów zawierają funkcji, które są wykonywane po ustawieniu, zmianie lub uzyskaniu dostępu do właściwości.
Właściwość | Typ deskryptora | Wartość domyślna z Object.defineProperty() |
Opis |
---|---|---|---|
[[Value]] |
Dane | undefined |
Zawiera wartość właściwości. |
[[Writable]] |
Dane | false |
Określa, czy możesz zmienić wartość właściwości. |
[[Get]] |
akcesor | undefined |
Funkcja getter właściwości, która jest wykonywana, gdy usługi. |
[[Set]] |
akcesor | undefined |
Funkcja setter właściwości, która jest wykonywana, gdy właściwość jest ustawiona lub zmieniona. |
[[Configurable]] |
Obie opcje | false |
Jeśli jest to false , usługi nie można usunąć ani jej
nie można zmieniać atrybutów. Jeśli jest to false i
[[Writable]] to true , wartość właściwości może
można zmienić. |
[[Enumerable]] |
Obie opcje | false |
Jeśli ma to wartość true , możesz iterować usługę za pomocą funkcji
pętle for...in lub statyczny Object.keys()
. |
Każda z tych właściwości używa tego samego skrótu co [[Prototype]]
, co wskazuje
że dostęp do tych usług nie jest możliwy bezpośrednio. Zamiast tego użyj
Metoda statyczna Object.defineProperty()
do definiowania lub modyfikowania właściwości
obiektu. Funkcja Object.defineProperty()
akceptuje 3 argumenty: obiekt, na którym działa,
klucz właściwości, który ma zostać utworzony lub zmodyfikowany, oraz obiekt zawierający
deskryptory powiązane z tworzoną lub modyfikowaną usługą.
Domyślnie usługi tworzone za pomocą usługi Object.defineProperty()
nie można zapisywać, wyliczać ani konfigurować. Jednak każda usługa, którą utworzysz,
jako część literału obiektu lub przy użyciu notacji kropki bądź nawiasu
możliwy do zapisu, wyliczania i konfigurowania.
const myObj = {};
Object.defineProperty(myObj, 'myProperty', {
value: true,
writable: false
});
myObj.myProperty;
> true
myObj.myProperty = false;
myObj.myProperty;
> true
Jeśli na przykład [[Writable]]
ma wartość false
, próba ustawienia nowej wartości
dla powiązanej usługi przechodzi dyskryminację poza trybem ścisłym i zwraca
w trybie ścisłym:
{
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
Efektywne korzystanie z deskryptorów to dość zaawansowana koncepcja,
zrozumienie struktury wewnętrznej obiektu jest kluczem do zrozumienia
składni używanych podczas pracy z obiektami na bardziej popularne sposoby. Przykład:
te pojęcia wchodzą w życie podczas korzystania z metody statycznej Object.create()
,
co daje precyzyjną kontrolę nad wszelkimi prototypami połączonymi
obiektu.
Object.create()
tworzy nowy obiekt, używając istniejącego obiektu jako obiektu
i prototypem. Dzięki temu nowy obiekt odziedziczy właściwości i metody z innego
obiektu zdefiniowanego przez użytkownika w taki sam sposób, w jaki obiekty dziedziczą właściwości z obiektu
Wbudowany prototyp języka Object
w języku JavaScript. Gdy wywołujesz aplikację Object.create()
z:
obiektu jako argumentu, tworzy pusty obiekt z przekazanym obiektem jako
swojego prototypu.
const myCustomPrototype = {
'myInheritedProp': 10
};
const newObject = Object.create( myCustomPrototype );
newObject;
> Object { }
<prototype>: Object { myInheritedProp: 10 }
myInheritedProp: 10
<prototype>: Object { … }
Funkcja Object.create
może przyjąć drugi argument określający własne właściwości obiektu
nowo utworzonego obiektu o składni podobnej do Object.defineProperty()
:
czyli kluczy mapowania obiektów do zestawu atrybutów deskryptora:
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 }
W tym przykładzie nowy obiekt (myObj
) używa literału obiektu
(myCustomPrototype
) jako prototyp, który zawiera odziedziczone
Object.prototype
, w wyniku czego powstała szereg odziedziczonych prototypów
łańcuch prototypów. Każdy obiekt ma prototyp – nieważne, czy jest przypisany, czy dziedziczony.
który ma przypisany lub odziedziczony prototyp. Ta sieć kończy się o
Prototyp null
, który nie ma własnego prototypu.
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 { … }
Właściwości zawarte w prototypie wartości są dostępne na „najwyższym poziomie” bez konieczności bezpośredniego dostępu do właściwości prototypu:
const objectLiteral = {
"value" : true
};
objectLiteral;
> Object { value: true }
value: true
<prototype>: Object { … }
objectLiteral.toString();
"[object Object]"
Ten wzorzec odnosi się do całego łańcucha prototypów powiązanego z obiektu: gdy próbuje uzyskać dostęp do właściwości, tłumacz usługę na poszczególnych „poziomach” prototypowego łańcucha (od góry do dołu), znajduje właściwość lub kończy się łańcuch:
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."
Sprawdź swoją wiedzę
Które deskryptory są akcesorami?
[[Get]]
[[Set]]
[[Writable]]