Atribut Deskriptor adalah konsep baru yang ditambahkan dalam ES5, dan fungsinya adalah menambahkan lebih banyak kontrol ke properti objek.
Object.defineproperty
Untuk mempelajari deskriptor atribut, pertama -tama kita harus berbicara tentang objek. Metode Defineproperty. Tujuan dari metode ini adalah untuk mendefinisikan properti baru untuk objek atau memodifikasi properti yang ada. Prototipe adalah sebagai berikut:
Salinan kode adalah sebagai berikut:
Object.defineproperty (OBJ, prop, deskriptor)
Contoh Penggunaan:
Salinan kode adalah sebagai berikut:
var obj = {};
Object.defineproperty (obj, 'attr', {value: 1});
Kode di atas menambahkan atribut bernama ATTR ke objek OBJ, dengan nilai 1. Setara dengan:
Salinan kode adalah sebagai berikut:
var obj = {};
obj.attr = 1;
Sebagai perbandingan, penulisan objek. Defineproperty tampaknya lebih rumit. Namun, rahasia terbesarnya terletak pada parameter ketiga.
Deskriptor data
Dengan asumsi bahwa kami ingin ATTR adalah atribut read-only, kami dapat menambahkan deskriptor data yang dapat ditulis:
Salinan kode adalah sebagai berikut:
var obj = {};
Object.defineproperty (obj, 'attr', {
Nilai: 1,
Tulisan: Salah
});
console.log (obj.attr);
obj.attr = 2; // gagal
console.log (obj.attr);
Jalankan program di atas dan Anda akan menemukan bahwa nilai attr yang dicetak dua kali adalah 1, yang berarti bahwa penulisan atribut gagal. Namun, hasil ini akan sedikit tidak dapat dijelaskan, karena pelaksanaan pernyataan penugasan tidak memiliki pengecualian, tetapi gagal. Bayangkan saja bahwa jika masalah seperti itu terjadi dalam kode blockbuster, akan sulit untuk memecahkan masalahnya. Bahkan, selama kode dijalankan dalam mode ketat, pengecualian akan dihasilkan:
Salinan kode adalah sebagai berikut:
'Gunakan ketat'; // Masukkan mode ketat
var obj = {};
Object.defineproperty (obj, 'attr', {
Nilai: 1,
Tulisan: Salah
});
obj.attr = 2; // Lemparkan pengecualian
Mari kita lihat deskriptor data lain yang dapat dihitung, yang dapat mengontrol apakah atribut dapat disebutkan. Jika Anda cukup mendefinisikan properti, properti ini dapat disebutkan dalam untuk ... di loop:
Salinan kode adalah sebagai berikut:
var obj = {};
obj.attr = 1;
untuk (var i di obj) {console.log (obj [i]); }
Hancur dapat "menyembunyikan" itu:
var obj = {};
Object.defineproperty (obj, 'attr', {
Nilai: 1,
Hancur: Salah
});
untuk (var i di obj) {console.log (obj [i]); }
Jalankan kode di atas dan Anda akan menemukan bahwa konsol tidak menghasilkan apa -apa, karena atribut ATTRIBUT tidak dapat disebutkan saat ini.
Karena itu, Anda mungkin memiliki pertanyaan: dapatkah deskriptor atribut dimodifikasi? Misalnya, dapatkah properti baca hanya didefinisikan sebagai writable lagi? Sebenarnya, ini tergantung pada deskriptor data lain yang dapat dikonfigurasi, yang dapat mengontrol apakah deskriptor atribut dapat diubah.
Salinan kode adalah sebagai berikut:
var obj = {};
Object.defineproperty (obj, 'attr', {
Nilai: 1,
Tulisan: Salah,
dapat dikonfigurasi: Benar
});
Object.defineproperty (obj, 'attr', {
Tulisan: Benar
});
obj.attr = 2;
Kode di atas pertama-tama mendefinisikan ATTR sebagai atribut hanya baca, dan kemudian mendefinisikannya kembali sebagai yang dapat ditulis. Jadi tulisan ke Attr berhasil.
Access Descriptor
Deskriptor akses mirip dengan Get/Set Accessor di Object-Oriented.
Salinan kode adalah sebagai berikut:
var obj = {};
Object.defineproperty (obj, 'attr', {
set: function (val) {this._attr = math.max (0, val); },
get: function () {return this._attr; }
});
obj.attr = -1;
console.log (obj.attr); // 0
Dalam kode di atas, akses ke ATTR sebenarnya menjadi akses ke _ATTR, dan nilai minimum dibatasi ke 0 dalam fungsi SET.
Dapatkan deskriptor atribut
Yang disebutkan di atas adalah semua deskriptor atribut pengaturan, jadi bagaimana cara mendapatkan deskriptor yang ditetapkan? Object.getOwnPropertyDescriptor dapat melakukan ini.
Salinan kode adalah sebagai berikut:
var obj = {};
Object.defineproperty (obj, 'attr', {
Nilai: 1,
Tulisan: Salah,
dapat dikonfigurasi: Benar
});
var desc = object.getOwnPropertyDescriptor (obj, 'attr');
Console.dir (desc);
Kontrol objek
Object.defineproperty yang disebutkan sebelumnya beroperasi pada properti objek, sedangkan tiga metode yang disebutkan di bawah ini beroperasi langsung pada objek.
Object.PreventExtensions dapat mencegah objek memiliki properti baru:
Salinan kode adalah sebagai berikut:
var obj = {};
obj.attr = 1;
Object.preventextensions (OBJ);
obj.attr2 = 2; //gagal
Object.seal dapat membuat objek hanya nilai properti yang tersisa untuk dimodifikasi (jika properti hanya baca, bahkan nilai properti tidak dapat dimodifikasi):
Salinan kode adalah sebagai berikut:
var obj = {};
obj.attr = 1;
Object.seal (OBJ);
obj.attr = 1.5;
hapus obj.attr; // gagal
Object.freeze dapat membuat objek benar -benar tidak dimodifikasi:
Salinan kode adalah sebagai berikut:
var obj = {};
obj.attr = 1;
Object.freeze (OBJ);
obj.attr = 1.5; // gagal
obj.attr2 = 2; //gagal
Kemudian Anda mungkin bertanya lagi, bagaimana Anda tahu jika suatu objek telah dicegah eksteks, segel atau beku? Jawabannya adalah memanggil objek. Penggunaan ketiga fungsi ini relatif sederhana dan tidak lagi rumit.
Secara umum, objek dapat dikontrol secara ketat melalui deskriptor atribut dan kekakuan logika program diperkuat. Satu -satunya kelemahan adalah bahwa ES5 pada dasarnya diimplementasikan di IE9 (IE9 belum mendukung mode ketat). Mempertimbangkan bahwa saham IE8 domestik masih relatif tinggi, serangkaian hal ini hanya dapat digunakan di browser seluler dan node.js.