Laman » Pengekodan » Panduan Ultimate untuk Getters dan Setters dalam JavaScript

    Panduan Ultimate untuk Getters dan Setters dalam JavaScript

    Getters dan setter adalah fungsi atau kaedah yang digunakan untuk dapatkan dan ditetapkan nilai pembolehubah. Konsep pengatur adalah biasa dalam pengaturcaraan komputer: hampir semua bahasa pengaturcaraan tingkat tinggi datang dengan satu set sintaks untuk melaksanakan getter dan setter, termasuk JavaScipt.

    Dalam siaran ini, kita akan melihat apa penentu getters, dan bagaimana membuat dan menggunakannya dalam JavaScript.

    Getters-setters and encapsulation

    Idea getters dan setter sentiasa disebut bersempena dengan pengkapsulan. Pengekuatan boleh difahami dengan dua cara.

    Pertama, ia adalah penubuhan data-getter-setters trio untuk mengakses dan mengubah suai data tersebut. Takrif ini berguna apabila beberapa operasi, seperti pengesahan, perlu dilakukan dilakukan pada data sebelum menyimpan atau melihat ia-getter dan penyedia menyediakan rumah yang sempurna untuknya.

    Kedua, terdapat definisi yang lebih ketat mengikut pengkapsulan yang dilakukan menyembunyikan data, untuk menjadikannya tidak boleh diakses daripada kod lain, kecuali melalui getters dan setters. Dengan cara ini kita tidak berakhir secara tidak sengaja menggantikan data penting dengan beberapa kod lain dalam program ini.

    Buat getters dan setter

    1. Dengan kaedah

    Sejak getters dan setter adalah pada dasarnya berfungsi yang mengambil / menukar nilai, ada lebih daripada satu cara untuk mencipta dan menggunakannya. Cara pertama adalah:

     var obj = foo: 'ini adalah nilai foo', getFoo: function () return this.foo; , setFoo: function (val) this.foo = val;  console.log (obj.getFoo ()); // "ini adalah nilai foo" obj.setFoo ('halo'); console.log (obj.getFoo ()); // "hello"

    Ini adalah cara yang paling mudah untuk mencipta getter dan setter. Ada harta benda foo dan terdapat dua kaedah: getFoo dan setFoo kepada kembali dan serahkan nilai kepada harta itu.

    2. Dengan kata kunci

    Lebih banyak lagi “rasmi” dan cara yang mantap untuk membuat getters dan setter adalah dengan menggunakan dapatkan dan ditetapkan kata kunci.

    Untuk buat pencari, letakkan dapatkan kata kunci di hadapan perisytiharan fungsi yang akan berfungsi sebagai kaedah getter, dan menggunakan ditetapkan kata kunci dengan cara yang sama buat setter. Sintaks ini adalah seperti berikut:

     var obj = fooVal: 'ini adalah nilai foo', dapatkan foo () return this.fooVal; , set foo (val) this.fooVal = val;  console.log (obj.foo); // "ini adalah nilai foo" obj.foo = 'halo'; console.log (obj.foo); // "hello" 

    Perhatikan bahawa data hanya boleh dilakukan disimpan di bawah nama hartanah (fooVal) itu berbeza dari nama metode getter-setter (foo) kerana harta yang memegang getter-setter tidak dapat memegang data juga.

    Cara mana lebih baik?

    Sekiranya anda memilih untuk membuat getters dan setter dengan kata kunci, anda boleh menggunakannya pengendali tugasan untuk menetapkan data dan juga pengendali titik untuk mendapatkan data, dengan cara yang sama anda akan mengakses / menetapkan nilai harta tetap.

    Walau bagaimanapun, jika anda memilih cara pertama pengatur kod dan penyusun, anda perlu memanggil kaedah penyetor dan pengambil menggunakan sintaks panggilan fungsi kerana mereka adalah fungsi biasa (tidak ada yang istimewa seperti yang dibuat menggunakan dapatkan dan ditetapkan kata kunci).

    Juga, ada peluang anda mungkin berakhir secara tidak sengaja memberikan beberapa nilai lain kepada sifat-sifat yang memegang kaedah-kaedah pemeteraian dan kehilangan mereka sepenuhnya! Sesuatu yang anda tidak perlu bimbang tentang kaedah kemudian.

    Jadi, anda dapat melihat mengapa saya berkata teknik kedua lebih kuat.

    Timpa pencegahan

    Jika atas sebab tertentu anda lebih suka teknik pertama, buatlah sifat-sifat yang memegang kaedah getter-setter baca sahaja dengan mewujudkannya menggunakan Object.defineProperties. Hartanah dicipta melalui Object.defineProperties, Object.defineProperty dan Reflect.defineProperty konfigurasi secara automatik kepada boleh tulis: palsu yang bermaksud baca sahaja:

     / * Menimpa pencegahan * / var obj = foo: 'ini adalah nilai foo'; Object.defineProperties (obj, 'getFoo': value: function () return this.foo;, 'setFoo': value: function (val) this.foo = val;); obj.getFoo = 66; // getFoo tidak akan ditimpa! console.log (obj.getFoo ()); // "ini adalah nilai foo" 

    Operasi di dalam getters dan setter

    Sebaik sahaja anda memperkenalkan getters dan setter, anda boleh teruskan dan menjalankan operasi pada data sebelum menukar atau mengembalikannya.

    Dalam kod di bawah, dalam fungsi getter data itu disambung dengan rentetan sebelum dikembalikan, dan dalam fungsi setter pengesahan sama ada nilai itu adalah nombor atau tidak dilakukan sebelum mengemaskini n.

     var obj = n: 67, dapatkan id () return 'ID adalah:' + this.n; , set id (val) if (typeof val === 'number') this.n = val;  console.log (obj.id); // "ID adalah: 67" obj.id = 893; console.log (obj.id); // "ID adalah: 893" obj.id = 'halo'; console.log (obj.id); // "ID adalah: 893" 

    Lindungi data dengan getters dan setter

    Setakat ini, kami membincangkan penggunaan getters dan setters dalam konteks enkapsulasi pertama. Mari kita beralih kepada yang kedua, iaitu, bagaimana menyembunyikan data dari kod luar dengan bantuan getters dan setters.

    Data tidak dilindungi

    Penubuhan getters dan setter tidak bermakna data hanya boleh diakses dan diubah menerusi kaedah tersebut. Dalam contoh berikut, ia berubah secara langsung tanpa menyentuh kaedah getter dan setter:

     var obj = fooVal: 'ini adalah nilai foo', dapatkan foo () return this.fooVal; , set foo (val) this.fooVal = val;  obj.fooVal = 'halo'; console.log (obj.foo); // "hello" 

    Kami tidak menggunakan setter tetapi terus mengubah data (fooVal). Data yang kami mulakan di dalamnya obj sudah tiada sekarang! Untuk mengelakkan perkara ini daripada berlaku (secara tidak sengaja), anda memerlukan perlindungan untuk data anda. Anda boleh menambahnya dengan mengehadkan skop dari mana data anda tersedia. Anda boleh melakukannya dengan baik pelupusan blok atau fungsi scoping.

    1. Blok pelbagaian

    Salah satu cara ialah gunakan skop blok di mana data akan ditakrifkan menggunakan biarlah kata kunci yang mana menghadkan skopnya ke blok itu.

    A ruang lingkup blok boleh dibuat dengan meletakkan kod anda di dalam sepasang kurungan keriting. Setiap kali anda membuat skop blok pastikan untuk Tinggalkan komen di atasnya meminta penyokong gigi dibiarkan bersendirian, sehingga tiada siapa menghilangkan pendakap dengan kesilapan berfikir mereka adalah beberapa pendakap tambahan yang berlebihan dalam kod atau tambah label kepada skop blok.

     / * BLOCK SCOPE, biarkan penyokong sahaja! * / let fooVal = 'ini adalah nilai foo'; var obj = get foo () return fooVal; , tetapkan foo (val) fooVal = val fooVal = 'halo'; // tidak akan menjejaskan fooVal di dalam konsol blok.log (obj.foo); // "ini adalah nilai foo"

    Menukar / mencipta fooValdi luar blok tidak akan menjejaskan yang fooVal dirujuk di dalam penetapan getters.

    2. Pengukuran fungsi

    Cara yang lebih biasa untuk melindungi data dengan scoping adalah dengan menyimpan data di dalam fungsi dan kembali objek dengan getters dan setter dari fungsi itu.

     fungsi myobj () var fooVal = 'ini adalah nilai foo'; kembali get foo () return fooVal; , tetapkan foo (val) fooVal = val fooVal = 'halo'; // tidak akan menjejaskan fooVal kami var obj = myobj (); console.log (obj.foo); // "ini adalah nilai foo"

    Objek (dengan foo () getter-setter di dalamnya) yang dikembalikan oleh myobj () fungsi adalah disimpan dalam obj, dan kemudian obj digunakan untuk panggil pengintip dan setter.

    3. Perlindungan data tanpa scoping

    Terdapat juga cara lain yang anda boleh melindungi data anda daripada ditimpa tulisan tanpa menghadkan skopnya. Logik di belakangnya seperti ini: bagaimana anda boleh menukar sekeping data jika anda tidak tahu apa yang dipanggil?

    Jika data mempunyai tidak begitu mudah ubah nama / nama hartanah, kemungkinannya tidak seorang pun (bahkan diri kita sendiri) akan mengakhiri penulisannya dengan memberikan beberapa nilai kepada nama pembolehubah itu / nama.

     var obj = s89274934764: 'ini adalah nilai foo', dapatkan foo () return this.s89274934764; , tetapkan foo (val) this.s89274934764 = val;  console.log (obj.foo); // "ini adalah nilai foo" 

    Lihat, itulah satu cara untuk mengatasi masalah. Walaupun nama yang saya pilih bukanlah yang benar-benar baik, anda juga boleh menggunakan nilai atau simbol rawak untuk membuat nama hartanah seperti yang dicadangkan oleh Derick Bailey dalam catatan blog ini. Matlamat utama adalah untuk menyimpan data yang tersembunyi dari kod lain dan biarkan pasangan getter-setter mengakses / mengemas kininya.

    Bilakah anda perlu menggunakan getters dan setters?

    Sekarang ada soalan besar: adakah anda mula menyerahkan getters dan setters kepada semua data anda sekarang?

    Jika anda menyembunyikan data, maka ada tiada pilihan lain.

    Tetapi jika data anda dilihat oleh kod lain adalah baik-baik saja, adakah anda masih perlu menggunakan setter getter hanya untuk membungkusnya dengan kod yang melakukan beberapa operasi di atasnya? Saya akan katakan ya. Kod menambah sehingga tidak lama lagi. Mewujudkan unit mikro data individu dengan pemerolehan sendiri memberikan anda kemerdekaan tertentu untuk bekerja pada data tersebut tanpa menjejaskan bahagian lain kod.