-->
Menerapkan Variabel Pribadi dalam JavaScript

Menerapkan Variabel Pribadi dalam JavaScript


JavaScript(atau ECMAScript) adalah bahasa pemrograman yang mendukung web. Dibuat pada Mei 1995 oleh Brendan Eich, ia menemukan tempatnya sebagai teknologi yang banyak digunakan dan serbaguna. Terlepas dari keberhasilannya, kritik tersebut mendapat bagian yang adil, terutama untuk keanehan. Hal-hal seperti objek yang dilemparkan ke bentuk string ketika digunakan sebagai indeks, 1 == "1" mengembalikan nilai true, atau yang terkenal membingungkan kata kunci ini. Namun kekhasan yang sangat menarik adalah adanya berbagai teknik untuk privasi variabel.

Dalam kondisi saat ini, tidak ada cara "langsung" untuk membuat variabel pribadi dalam JavaScript. Dalam bahasa lain, Anda dapat menggunakan kata kunci pribadi atau menggarisbawahi dan semuanya berfungsi, tetapi privasi variabel dalam JavaScript membawa karakteristik yang membuatnya tampak lebih mirip dengan sifat bahasa yang muncul alih-alih fungsi yang dimaksudkan. Mari kita perkenalkan beberapa latar belakang untuk masalah kita.

Kata kunci "var"


Sebelum 2015, pada dasarnya ada satu cara untuk membuat variabel, dan itu adalah kata kunci var. var adalah fungsi-lingkup, yang berarti bahwa variabel yang dipakai dengan kata kunci hanya akan dapat diakses oleh kode dalam fungsi. Ketika di luar fungsi, atau "global" pada dasarnya, variabel akan dapat diakses oleh apa pun yang dieksekusi setelah definisi variabel. Jika Anda mencoba mengakses variabel dalam lingkup yang sama sebelum definisi, Anda akan mendapatkan undefined daripada kesalahan Ini karena cara kata kunci var "kerekan."

// Define "a" in global scope var a = 123; // Define "b" in function scope (function() { console.log(b); //=> Returns "undefined" instead of an error due to hoisting. var b = 456; })(); console.log(a); // => 123 console.log(b); // Throws "ReferenceError" exception, because "b" cannot be accessed from outside the function scope

Kelahiran variabel ES6


Pada 2015, ES6 / ES2015 dibuat resmi, dan dengan itu muncul dua kata kunci variabel baru: let dan const. Keduanya diblok-blok, artinya variabel yang dibuat dengan kata kunci akan dapat diakses dari apa pun dalam pasangan kawat gigi yang sama. Sama seperti dengan var, tetapi variabel let dan const tidak dapat diakses di luar lingkup blok dengan loop, fungsi, jika pernyataan, kawat gigi, dll.

const a = 123; // Block scope example #1 if
(true) { const b = 345; } // Block scope example #2 { const c = 678; } console.log(a); // 123
console.log(b); // Throws "ReferenceError" because "b" cannot be accessed from outside the
block scope. console.log(c); // Throws "ReferenceError" because "b" cannot be accessed
from outside the block scope.


Karena kode di luar ruang lingkup tidak dapat mengakses variabel, kami mendapatkan sifat privasi yang muncul. Kami akan membahas beberapa teknik untuk mengimplementasikannya dengan cara yang berbeda.

Menggunakan fungsi


Karena fungsi dalam JavaScript juga adalah blok, semua kata kunci variabel bekerja dengannya. Selain itu, kita dapat menerapkan pola desain yang sangat berguna yang disebut "modul."

Pola Desain Modul


Google mengandalkan Kamus Oxford untuk mendefinisikan "modul":

Salah satu dari sejumlah unit yang berbeda tetapi saling terkait dari mana suatu program dapat dibangun atau di mana suatu kegiatan yang kompleks dapat dianalisis.

- Definisi "Modul" 1.2

Pola desain modul sangat berguna dalam JavaScript karena menggabungkan komponen publik dan swasta dan memungkinkan kita untuk memecah program menjadi komponen yang lebih kecil, hanya memaparkan apa yang harus dapat diakses oleh bagian lain dari program melalui proses yang disebut "enkapsulasi." metode ini, kami hanya mengekspos apa yang perlu digunakan dan dapat menyembunyikan sisa implementasi yang tidak perlu dilihat. Kita dapat memanfaatkan ruang lingkup fungsi untuk mengimplementasikan ini.

const CarModule = () => { let milesDriven = 0; let speed = 0; 
const accelerate = (amount) => { speed += amount; milesDriven += speed; }
const getMilesDriven = () => milesDriven; // Using the "return" keyword, you can control what gets
// exposed and what gets hidden. In this case, we expose // only the accelerate() and getMilesDriven() function. return { accelerate, getMilesDriven } };
const testCarModule = CarModule(); testCarModule.accelerate(5); testCarModule.accelerate(4); console.log(testCarModule.getMilesDriven());


Dengan ini, kita bisa mendapatkan jumlah mil yang digerakkan, serta jumlah akselerasi, tetapi karena pengguna tidak memerlukan akses ke kecepatan dalam hal ini, kita dapat menyembunyikannya hanya dengan mengekspos akselerasi () dan getMilesDriven ( ) metode. Pada dasarnya, kecepatan adalah variabel pribadi, karena hanya dapat diakses oleh kode di dalam lingkup blok yang sama. Manfaat untuk variabel pribadi mulai menjadi jelas dalam situasi ini. Saat Anda menghapus kemampuan untuk mengakses variabel, fungsi, atau komponen internal lainnya, Anda mengurangi area permukaan untuk kesalahan yang disebabkan oleh orang lain yang keliru menggunakan sesuatu yang tidak seharusnya.

Cara alternatif


Dalam contoh kedua ini, Anda akan melihat penambahan kata kunci ini. Ada perbedaan antara fungsi panah ES6 (=>) dan fungsi tradisional () {}. Dengan kata kunci fungsi, Anda dapat menggunakan ini, yang akan terikat pada fungsi itu sendiri, sedangkan fungsi panah tidak mengizinkan segala jenis penggunaan kata kunci ini. Keduanya sama-sama cara yang valid untuk membuat modul. Gagasan intinya adalah untuk mengekspos bagian yang harus diakses dan meninggalkan bagian lain yang tidak boleh berinteraksi, karenanya data publik dan pribadi.

function CarModule() { let milesDriven = 0; let speed = 0; 
// In this case, we instead use the "this" keyword, // which refers to CarModule this.accelerate = (amount) => { speed += amount;
milesDriven += speed; } this.getMilesDriven = () => milesDriven; } const testCarModule = new CarModule();
testCarModule.accelerate(5); testCarModule.accelerate(4); console.log(testCarModule.getMilesDriven());


Masukkan Kelas ES6

Kelas adalah tambahan lain yang datang dengan ES6. Kelas pada dasarnya adalah gula sintaksis - dengan kata lain, masih berfungsi, tetapi berpotensi "mempermanisnya" menjadi bentuk yang lebih mudah untuk diekspresikan. Dengan kelas, privasi variabel hampir tidak mungkin terjadi tanpa membuat beberapa perubahan besar pada kode. .

Mari kita lihat contoh kelas.

class CarModule { /* milesDriven = 0; speed = 0; */ 
constructor() { this.milesDriven = 0; this.speed = 0; } accelerate(amount) { this.speed += amount; this.milesDriven += this.speed; } getMilesDriven() { return this.milesDriven; } }
const testCarModule = new CarModule(); testCarModule.accelerate(5); testCarModule.accelerate(4); console.log(testCarModule.getMilesDriven());


Salah satu hal pertama yang menonjol adalah bahwa milesDriven dan variabel kecepatan berada di dalam fungsi constructor (). Perhatikan bahwa Anda juga dapat mendefinisikan variabel di luar konstruktor (seperti yang ditunjukkan dalam komentar kode), tetapi secara fungsional keduanya tetap sama. Masalahnya adalah bahwa variabel-variabel ini akan menjadi publik dan dapat diakses oleh elemen-elemen di luar kelas.

Mari kita lihat beberapa cara untuk mengatasinya.

Menggunakan garis bawah


Dalam kasus di mana privasi adalah untuk mencegah kolaborator membuat beberapa kesalahan katastropik, mengawali variabel dengan garis bawah (_), meskipun masih "terlihat" di luar, bisa cukup untuk memberi sinyal kepada pengembang, "Jangan sentuh variabel ini. "Jadi, misalnya, kami sekarang memiliki yang berikut:

// This is the new constructor for the class. Note that it could 
// also be expressed as the following outside of constructor(). /* _milesDriven = 0; _speed = 0; */
constructor() { this._milesDriven = 0; this._speed = 0; }


Meskipun ini berfungsi untuk kasus penggunaan spesifiknya, masih aman untuk mengatakan bahwa ini kurang ideal di banyak tingkatan. Anda masih dapat mengakses variabel tetapi Anda juga harus memodifikasi nama variabel di atas itu.

#Menempatkan semua yang ada di dalam konstruktor

Secara teknis, ada metode untuk privasi variabel di kelas yang dapat Anda gunakan saat ini, dan itu menempatkan semua variabel dan metode di dalam fungsi constructor (). Mari lihat.

class CarModule { constructor() { let milesDriven = 0; 
let speed = 0; this.accelerate = (amount) => { speed += amount; milesDriven += speed; }
this.getMilesDriven = () => milesDriven; } } const testCarModule = new CarModule(); testCarModule.accelerate(5); testCarModule.accelerate(4); console.log(testCarModule.getMilesDriven()); console.log(testCarModule.speed); // undefined -- We have true variable privacy now.


Metode ini mencapai privasi variabel yang sesungguhnya dalam arti bahwa tidak ada cara untuk secara langsung mengakses variabel apa pun yang tidak sengaja diekspos. Masalahnya adalah bahwa kita sekarang memiliki, yah, kode yang tidak terlihat terlalu bagus dibandingkan dengan yang kita miliki sebelumnya, di samping fakta bahwa itu mengalahkan manfaat dari gula sintaksis yang kita miliki dengan kelas. Pada titik ini, kita mungkin juga menggunakan metode function ().

#Menggunakan WeakMap

Ada cara lain yang lebih kreatif untuk membuat variabel pribadi, dan itu menggunakan WeakMap (). Meskipun kedengarannya mirip dengan Peta, keduanya sangat berbeda. Sementara peta bisa mengambil semua jenis nilai sebagai kunci, WeakMap hanya mengambil objek dan menghapus nilai-nilai dalam WeakMap ketika kunci objek dikumpulkan sampah. Selain itu, WeakMap tidak dapat diulangi, artinya Anda harus memiliki akses ke referensi ke kunci objek untuk mengakses nilai. Ini membuatnya lebih berguna untuk membuat variabel pribadi, karena variabel-variabel tersebut secara efektif tidak terlihat.

class CarModule { constructor() { this.data = new WeakMap(); this.data.set(this, { milesDriven: 0, speed: 0 }); } accelerate(amount) { 
// In this version, we instead create a WeakMap and // use the "this" keyword as a key, which is not likely // to be used accidentally as a key to the WeakMap. const data = this.data.get(this); const speed = data.speed + amount;
const milesDriven = data.milesDriven + data.speed; this.data.set({ speed, milesDriven }); } this.getMilesDriven = () => this.data.get(this).milesDriven; }
const testCarModule = new CarModule(); testCarModule.accelerate(5); testCarModule.accelerate(4); console.log(testCarModule.getMilesDriven()); console.log(testCarModule.data); //=> WeakMap { [items unknown] } -- This data cannot be accessed easily from the outside!


Solusi ini bagus untuk mencegah penggunaan data yang tidak disengaja, tetapi itu tidak benar-benar pribadi, karena masih dapat diakses dari luar lingkup dengan mengganti ini dengan CarModule. Selain itu, ini menambah kompleksitas dalam campuran dan, karenanya, bukan solusi yang paling elegan.

#Menggunakan simbol untuk mencegah tabrakan

Jika tujuannya adalah untuk mencegah tabrakan nama, ada solusi yang berguna menggunakan Simbol. Ini pada dasarnya adalah contoh yang dapat berperilaku sebagai nilai unik yang tidak akan pernah sama dengan apa pun, kecuali contoh uniknya sendiri. Berikut ini contoh tindakannya:

class CarModule { constructor() { this.speedKey = Symbol("speedKey"); 
this.milesDrivenKey = Symbol("milesDrivenKey"); this[this.speedKey] = 0; this[this.milesDrivenKey] = 0; } accelerate(amount) {
// It's virtually impossible for this data to be // accidentally accessed. By no means is it private, // but it's well out of the way of anyone who would
// be implementing this module. this[this.speedKey] += amount; this[this.milesDrivenKey] += this[this.speedKey]; } getMilesDriven() { return this[this.milesDrivenKey]; } }
const testCarModule = new CarModule(); testCarModule.accelerate(5); testCarModule.accelerate(4); console.log(testCarModule.getMilesDriven()); console.log(testCarModule.speed); // => undefined -- we would need to access the internal keys to access the variable. Like the underscore solution, this method more or less relies on naming conventions to prevent confusion.


Proposal lapangan kelas swasta TC39

Baru-baru ini, sebuah proposal baru diperkenalkan yang akan memperkenalkan variabel pribadi ke kelas. Ini agak sederhana: letakkan # di depan nama variabel, dan itu menjadi pribadi. Tidak diperlukan perubahan struktural tambahan.

class CarModule { #speed = 0 #milesDriven = 0 accelerate(amount) { 
// It's virtually impossible for this data to be // accidentally accessed. By no means is it private, // but it's well out of the way of anyone who would
// be implementing this module. this.#speed += amount; this.#milesDriven += speed; } getMilesDriven() { return this.#milesDriven; } }
const testCarModule = new CarModule(); testCarModule.accelerate(5); testCarModule.accelerate(4); console.log(testCarModule.getMilesDriven()); console.log(testCarModule.speed); //=> undefined -- we would need to access the internal keys to access the variable.


Proposal bidang kelas privat tidak standar dan tidak dapat dilakukan tanpa menggunakan Babel pada tulisan ini, jadi Anda harus menunggu sedikit agar dapat digunakan di browser utama, Node, dll.

Kesimpulan


Itu meringkas berbagai cara Anda dapat menerapkan variabel pribadi dalam JavaScript. Tidak ada satu cara "benar" untuk melakukannya. Ini akan bekerja untuk kebutuhan yang berbeda, basis kode yang ada, dan kendala lainnya. Meskipun masing-masing memiliki kelebihan dan kekurangan, pada akhirnya, semua metode sama-sama valid selama mereka secara efektif menyelesaikan masalah Anda .

Terima kasih sudah membaca! Saya harap ini memberikan beberapa wawasan tentang bagaimana ruang lingkup dan privasi variabel dapat diterapkan untuk meningkatkan kode JavaScript Anda. Ini adalah teknik yang ampuh dan dapat mendukung begitu banyak metode berbeda dan membuat kode Anda lebih bermanfaat dan bebas bug. Cobalah beberapa contoh baru untuk diri Anda dan dapatkan perasaan yang lebih baik.

Subscribe to the latest article updates via email:

0 Response to "Menerapkan Variabel Pribadi dalam JavaScript "

Posting Komentar

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel