Sebagian besar interaksi Anda dengan properti objek kemungkinan akan tingkat permukaan, termasuk membuat literal objek, menetapkan, dan mengakses nilai properti menggunakan kunci. Namun, Anda dapat secara internal mengkonfigurasi properti sebuah objek untuk kontrol terperinci tentang bagaimana properti itu diakses, diubah, dan didefinisikan. Setiap properti objek memiliki kumpulan atribut yang tidak terlihat berisi metadata yang terkait dengan properti tersebut, yang disebut "properti deskripsi."
Ada dua jenis deskripsi yang terkait dengan properti: deskriptor data dan deskripsi aksesor. Deskriptor data berisi pasangan kunci dan nilai yang berisi nilai properti, terlepas dari apakah itu dapat ditulis, dikonfigurasi, atau dapat dienumerasi. Deskriptor pengakses berisi fungsi yang dijalankan saat properti diatur, diubah, atau diakses.
Properti | Jenis deskriptor | Nilai default dari Object.defineProperty() |
Deskripsi |
---|---|---|---|
[[Value]] |
Data | undefined |
Berisi nilai properti. |
[[Writable]] |
Data | false |
Menentukan apakah Anda dapat mengubah nilai properti. |
[[Get]] |
Pemberi akses | undefined |
Fungsi pengambil properti, yang dieksekusi saat diakses. |
[[Set]] |
Pemberi akses | undefined |
Fungsi penyetel properti, yang dijalankan saat properti diatur atau diubah. |
[[Configurable]] |
Keduanya | false |
Jika ini adalah false , properti tidak dapat dihapus dan
tidak dapat diubah. Jika ini adalah false dan
[[Writable]] adalah true , nilai properti dapat
masih diubah. |
[[Enumerable]] |
Keduanya | false |
Jika true , Anda dapat melakukan iterasi pada properti menggunakan
for...in loop atau Object.keys() statis
. |
Setiap properti ini menggunakan singkatan yang sama seperti [[Prototype]]
, yang menunjukkan
bahwa properti ini tidak
dimaksudkan untuk diakses secara langsung. Sebagai gantinya, gunakan
Metode statis Object.defineProperty()
untuk mendefinisikan atau mengubah properti suatu
. Object.defineProperty()
menerima tiga argumen: objek untuk ditindaklanjuti,
kunci properti yang akan dibuat atau
diubah, dan objek yang berisi atribut
deskripsi yang terkait dengan properti yang dibuat atau diubah.
Secara default, properti yang dibuat menggunakan Object.defineProperty()
tidak dapat ditulis, dienumerasi, atau dikonfigurasi. Namun, setiap properti yang Anda buat
baik sebagai bagian dari literal objek atau
menggunakan notasi titik atau tanda kurung adalah
dapat ditulis, dapat dienumerasi, dan dapat dikonfigurasi.
const myObj = {};
Object.defineProperty(myObj, 'myProperty', {
value: true,
writable: false
});
myObj.myProperty;
> true
myObj.myProperty = false;
myObj.myProperty;
> true
Misalnya, saat [[Writable]]
memiliki nilai false
, mencoba menetapkan nilai baru
untuk properti terkait gagal secara otomatis di luar mode ketat, dan menampilkan
error dalam mode ketat:
{
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
Membuat penggunaan deskriptor yang efektif adalah konsep yang cukup maju, tetapi
penting untuk memahami struktur internal
objek dalam memahami
sintaks yang digunakan untuk bekerja
dengan objek dengan cara yang lebih umum. Misalnya,
konsep ini ikut berperan saat menggunakan metode statis Object.create()
,
yang memberi Anda kontrol terperinci atas
setiap prototipe yang dilampirkan pada
.
Object.create()
membuat objek baru menggunakan objek yang sudah ada sebagai objeknya
prototipe. Hal ini memungkinkan objek baru mewarisi properti dan metode dari
objek yang ditentukan pengguna dengan cara yang sama
seperti objek yang mewarisi properti dari
Prototipe Object
bawaan JavaScript. Saat Anda memanggil Object.create()
dengan
sebagai argumen, objek tersebut akan dibuat dengan objek yang diteruskan sebagai
prototipenya.
const myCustomPrototype = {
'myInheritedProp': 10
};
const newObject = Object.create( myCustomPrototype );
newObject;
> Object { }
<prototype>: Object { myInheritedProp: 10 }
myInheritedProp: 10
<prototype>: Object { … }
Object.create
dapat mengambil argumen kedua yang menentukan properti sendiri untuk
objek yang baru dibuat menggunakan sintaksis yang mirip dengan Object.defineProperty()
—
yaitu, objek yang memetakan kunci ke serangkaian atribut deskriptor:
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 }
Dalam contoh ini, objek baru (myObj
) menggunakan literal objek
(myCustomPrototype
) sebagai prototipenya, yang berisi properti yang diwarisi
Object.prototype
, yang menghasilkan serangkaian prototipe yang diwariskan yang disebut
rantai prototipe. Setiap objek memiliki prototipe, baik yang ditugaskan maupun diwarisi,
yang memiliki prototipe yang ditugaskan atau diwariskan sendiri. Rantai ini berakhir pada
Prototipe null
, yang tidak memiliki prototipenya sendiri.
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 { … }
Properti yang terdapat dalam prototipe nilai tersedia pada "tingkat atas" tertentu, tanpa perlu mengakses properti prototipe secara langsung:
const objectLiteral = {
"value" : true
};
objectLiteral;
> Object { value: true }
value: true
<prototype>: Object { … }
objectLiteral.toString();
"[object Object]"
Pola ini berlaku untuk seluruh rantai prototipe yang terkait dengan objek: saat mencoba mengakses properti, penerjemah mencari properti properti di setiap "level" rantai prototipe, dari atas ke bawah, sampai menemukan properti atau rantai berakhir:
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."
Menguji pemahaman Anda
Deskripsi manakah yang merupakan pengakses?
[[Get]]
[[Set]]
[[Writable]]