Saya mencari-cari cara menggunakan Object.defineProperty
metode ini, tetapi tidak menemukan sesuatu yang layak.
Seseorang memberi saya potongan kode ini :
Object.defineProperty(player, "health", {
get: function () {
return 10 + ( player.level * 15 );
}
})
Tapi saya tidak mengerti. Terutama, get
itulah yang tidak bisa saya dapatkan (pun intended). Bagaimana cara kerjanya?
javascript
object
defineproperty
Chiller matematika
sumber
sumber
Jawaban:
Karena Anda mengajukan pertanyaan serupa , mari selangkah demi selangkah. Ini sedikit lebih lama, tetapi mungkin menghemat lebih banyak waktu daripada yang saya habiskan untuk menulis ini:
Properti adalah fitur OOP yang dirancang untuk pemisahan kode klien secara bersih. Misalnya, di beberapa toko elektronik Anda mungkin memiliki objek seperti ini:
Kemudian dalam kode klien Anda (toko online), Anda dapat menambahkan diskon ke produk Anda:
Kemudian, pemilik e-shop mungkin menyadari bahwa diskon tidak boleh lebih besar dari mengatakan 80%. Sekarang Anda perlu menemukan SETIAP kemunculan modifikasi diskon dalam kode klien dan menambahkan baris
Kemudian pemilik e-shop lebih lanjut dapat mengubah strateginya, seperti "jika pelanggan adalah reseller, diskon maksimal bisa 90%" . Dan Anda perlu melakukan perubahan di beberapa tempat lagi ditambah Anda harus ingat untuk mengubah garis-garis ini kapan saja strategi diubah. Ini desain yang buruk. Itu sebabnya enkapsulasi adalah prinsip dasar OOP. Jika konstruktornya seperti ini:
Kemudian Anda bisa mengubah metode
getDiscount
( accessor ) dansetDiscount
( mutator ). Masalahnya adalah bahwa sebagian besar anggota berperilaku seperti variabel umum, hanya diskon membutuhkan perawatan khusus di sini. Tetapi desain yang baik membutuhkan enkapsulasi dari setiap anggota data untuk menjaga kode dapat diperluas. Jadi, Anda perlu menambahkan banyak kode yang tidak melakukan apa-apa. Ini juga desain yang buruk, antipattern boilerplate . Kadang-kadang Anda tidak bisa hanya refactor bidang ke metode nanti (kode eshop dapat tumbuh besar atau beberapa kode pihak ketiga mungkin tergantung pada versi lama), sehingga boilerplate lebih sedikit jahat di sini. Tapi tetap saja, itu jahat. Itu sebabnya properti diperkenalkan ke banyak bahasa. Anda dapat menyimpan kode asli, cukup mengubah anggota diskon menjadi properti denganget
danset
blok:Perhatikan baris terakhir tetapi satu: tanggung jawab untuk nilai diskon yang benar dipindahkan dari kode klien (definisi e-shop) ke definisi produk. Produk bertanggung jawab untuk menjaga anggota datanya konsisten. Desain yang bagus adalah (secara kasar dikatakan) jika kode bekerja dengan cara yang sama dengan pikiran kita.
Begitu banyak tentang properti. Tapi javascript berbeda dari bahasa berorientasi objek murni seperti C # dan kode fitur-fiturnya berbeda:
Di C # , mentransformasikan bidang menjadi properti merupakan perubahan besar , jadi bidang publik harus dikodekan sebagai Properti yang Diimplementasikan Otomatis jika kode Anda mungkin digunakan dalam klien yang dikompilasi secara terpisah.
Dalam Javascript , properti standar (anggota data dengan pengambil dan penyetel yang dijelaskan di atas) ditentukan oleh deskriptor accessor (dalam tautan yang Anda miliki dalam pertanyaan Anda). Secara eksklusif, Anda dapat menggunakan deskriptor data (sehingga Anda tidak dapat menggunakan nilai yaitu dan disetel pada properti yang sama):
Kedua deskriptor dapat memiliki anggota ini:
for(var i in theObject)
; jika salah, itu tidak akan diulangi, tetapi masih dapat diakses sebagai publik* kecuali dalam mode ketat - dalam hal ini JS menghentikan eksekusi dengan TypeError kecuali jika tertangkap dalam blok try-catch
Untuk membaca pengaturan ini, gunakan
Object.getOwnPropertyDescriptor()
.Belajar dengan contoh:
Jika Anda tidak ingin mengizinkan kode klien menipu seperti itu, Anda dapat membatasi objek dengan tiga tingkat kurungan:
Object.isExtensible(<yourObject>)
untuk memeriksa apakah metode itu digunakan pada objek. Pencegahannya dangkal (baca di bawah).configurable: false
ke semua properti). GunakanObject.isSealed(<yourObject>)
untuk mendeteksi fitur ini pada objek. Segel itu dangkal (baca di bawah).writable: false
ke semua properti dengan deskriptor data). Properti Setter yang dapat ditulisi tidak terpengaruh (karena tidak memilikinya). Pembekuan itu dangkal : itu berarti bahwa jika properti adalah Obyek, propertinya TIDAK beku (jika Anda mau, Anda harus melakukan sesuatu seperti "deep freeze", mirip dengan kloning penyalinan dalam ). GunakanObject.isFrozen(<yourObject>)
untuk mendeteksinya.Anda tidak perlu repot dengan ini jika Anda menulis hanya beberapa baris yang menyenangkan. Tetapi jika Anda ingin membuat kode permainan (seperti yang Anda sebutkan dalam pertanyaan terkait), Anda harus benar-benar peduli dengan desain yang bagus. Coba Google sesuatu tentang antipatterns dan kode bau . Ini akan membantu Anda menghindari situasi seperti "Oh, saya harus menulis ulang kode saya sepenuhnya!" , itu bisa menyelamatkanmu dari keputusasaan selama berbulan-bulan jika ingin banyak kode. Semoga berhasil.
sumber
function Product(name,price) { this.name = name; this.price = price; var _discount; // private member Object.defineProperty(this,"discount",{ get: function() { return _discount; }, set: function(value) { _discount = value; if(_discount>80) _discount = 80; } }); } var sneakers = new Product("Sneakers",20); sneakers.discount = 50; // 50, setter is called sneakers.discount+= 20; // 70, setter is called sneakers.discount+= 20; // 80, not 90! alert(sneakers.discount); // getter is called
get
adalah fungsi yang dipanggil saat Anda mencoba membaca nilaiplayer.health
, seperti di:Secara efektif tidak jauh berbeda dari:
Kebalikan dari get diatur, yang akan digunakan saat Anda menetapkan nilai. Karena tidak ada setter, tampaknya menetapkan untuk kesehatan pemain tidak dimaksudkan:
Contoh yang sangat sederhana:
sumber
()
untuk menelepon ... Saya tidak mengerti apa idenya ketika mereka menemukan benda ini. Fungsinya benar-benar sama: jsbin.com/bugipi/edit?js,console,outputdefineProperty adalah metode pada Object yang memungkinkan Anda mengkonfigurasi properti untuk memenuhi beberapa kriteria. Berikut adalah contoh sederhana dengan objek karyawan dengan dua properti firstName & lastName dan menambahkan dua properti dengan menimpa metode toString pada objek.
Anda akan mendapatkan Output sebagai: Jameel Moideen
Saya akan mengubah kode yang sama dengan menggunakan defineProperty pada objek
Parameter pertama adalah nama objek dan kemudian parameter kedua adalah nama properti yang kita tambahkan, dalam kasus ini adalah toString dan kemudian parameter terakhir adalah objek json yang memiliki nilai akan menjadi fungsi dan tiga parameter dapat ditulis, dapat dihitung dan dapat dikonfigurasi. Sekarang, saya hanya menyatakan semuanya benar.
Jika Anda menjalankan contoh, Anda akan mendapatkan Output sebagai: Jameel Moideen
Mari kita mengerti mengapa kita membutuhkan tiga properti seperti dapat ditulis, enumerable dan dapat dikonfigurasi.
dapat ditulis
Salah satu bagian yang sangat menjengkelkan dari javascript adalah, jika Anda mengubah properti toString ke sesuatu yang lain misalnya
jika Anda menjalankan ini lagi, semuanya akan rusak. Mari kita ubah tulisan menjadi false. Jika menjalankan hal yang sama lagi, Anda akan mendapatkan output yang benar sebagai 'Jameel Moideen'. Properti ini akan mencegah menimpa properti ini nanti.
tak terhitung
jika Anda mencetak semua kunci di dalam objek, Anda dapat melihat semua properti termasuk toString.
jika Anda menetapkan enumerable menjadi false, Anda dapat menyembunyikan properti toString dari orang lain. Jika menjalankan ini lagi Anda akan mendapatkan firstName, lastName
dapat dikonfigurasi
jika seseorang kemudian mendefinisikan ulang objek di kemudian hari misalnya dihitung untuk true dan menjalankannya. Anda dapat melihat properti toString datang lagi.
Anda dapat membatasi perilaku ini dengan mengatur yang dapat dikonfigurasi ke false.
Referensi asli informasi ini dari Blog pribadi saya
sumber
Pada dasarnya,
defineProperty
adalah metode yang mengambil 3 parameter - objek, properti, dan deskriptor. Apa yang terjadi dalam panggilan khusus ini adalah"health"
propertiplayer
objek mendapatkan 10 ditambah 15 kali level objek pemain.sumber
ya tidak ada lagi fungsi yang diperluas untuk setup setter & pengambil ini contoh saya Object.defineProperty (obj, nama, func)
sumber
Object.defineProperty () adalah fungsi global..Tidak tersedia di dalam fungsi yang menyatakan objek sebaliknya. Anda harus menggunakannya secara statis ...
sumber
Ringkasan:
Object.defineProperty
digunakan untuk membuat properti baru pada objek pemain.Object.defineProperty
adalah fungsi yang secara native hadir dalam lingkungan runtime JS dan mengambil argumen berikut:Object.defineProperty(obj, prop, descriptor)
Objek deskriptor adalah bagian yang menarik. Di sini kita dapat mendefinisikan hal-hal berikut:
<boolean>
: Jikatrue
deskriptor properti dapat diubah dan properti dapat dihapus dari objek. Jika dapat dikonfigurasifalse
, properti deskriptor yang diteruskanObject.defineProperty
tidak dapat diubah.<boolean>
: Jikatrue
properti dapat ditimpa menggunakan operator penugasan.<boolean>
: Jikatrue
properti dapatfor...in
diulang dalam satu lingkaran. Juga saat menggunakanObject.keys
fungsi tombol akan hadir. Jika properti itufalse
mereka tidak akanfor..in
diulang menggunakan loop dan tidak muncul saat menggunakanObject.keys
.<function>
: Suatu fungsi yang dipanggil setiap kali dibutuhkan properti. Alih-alih memberikan nilai langsung, fungsi ini disebut dan nilai yang dikembalikan diberikan sebagai nilai properti<function>
: Suatu fungsi yang dipanggil setiap kali properti ditugaskan. Alih-alih mengatur nilai langsung, fungsi ini dipanggil dan nilai yang dikembalikan digunakan untuk mengatur nilai properti.Contoh:
sumber
sumber
Mendefinisikan properti baru secara langsung pada objek, atau memodifikasi properti yang ada pada objek, dan mengembalikan objek.
Penjelasan sederhana tentang define Property.
Kode contoh: https://jsfiddle.net/manoj_antony32/pu5n61fs/
sumber
sumber