Deskripsi properti

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]]