Pada artikel ini, kita akan melihat bagaimana javascript melewati referensi atau nilai bekerja dan perbedaan antara kedua metode tersebut
Daftar isi
- Pengantar javascript lewat referensi dan lewat nilai
- Javascript lulus dengan referensi
- Javascript melewati nilai
- Kata-kata Perpisahan
Pengantar javascript lewat referensi dan lewat nilai
Sebelum terjun ke fungsi javascript pass by reference atau pass by value, penting untuk memahami perbedaan antara primitif dan objek
Nilai-nilai primitif
Ini adalah nilai paling dasar yang dapat dipikirkan seseorang, yang meliputi, undefined, null, boolean, string, dan angka. Nilai primitif diteruskan oleh nilai dalam javascript
Sedangkan semua objek (termasuk fungsi) dilewatkan dengan referensi dalam javascript
Mari kita pahami apa itu pass by reference dan pass by value sebelum melihat contoh
Javascript lulus dengan referensi
Dalam Pass by Reference, suatu fungsi dipanggil dengan langsung meneruskan referensi/alamat variabel sebagai argumen. Mengubah argumen di dalam fungsi memengaruhi variabel yang dikirimkan dari luar fungsi. Dalam objek dan array Javascript dilewatkan dengan referensi
//javascript pass by reference function callByReference(varObj) { console.log("Inside Call by Reference Method"); varObj.a = 100; console.log(varObj); } let varObj = { a: 1 }; console.log("Before Call by Reference Method"); console.log(varObj); callByReference(varObj) console.log("After Call by Reference Method"); console.log(varObj); }Keluaran
Before Call by Reference Method {a: 1} Inside Call by Reference Method {a: 100} After Call by Reference Method {a: 100} _Javascript melewati nilai
Dalam javascript pass by value, fungsi dipanggil dengan langsung meneruskan nilai variabel sebagai argumen. Oleh karena itu, bahkan mengubah argumen di dalam fungsi tidak memengaruhi variabel yang dikirimkan dari luar fungsi
Penting untuk dicatat bahwa dalam javascript, semua argumen fungsi selalu diteruskan dengan nilai. Yaitu, JavaScript menyalin nilai dari variabel yang lewat ke dalam argumen di dalam fungsi
//javascript pass by value function square(x) { x = x * x; return x; } var y = 10; var result = square(y); console.log(y); // 10 -- no change console.log(result); // 100Penjelasan Kode
Seperti yang Anda lihat di sini, setelah kita meneruskan variabel y ke kotak fungsi, nilai y disalin ke variabel x dengan javascript (karenanya diteruskan dengan nilai)
Perhatikan bahwa meneruskan argumen fungsional dengan nilai tidak berdampak pada variabel asli itu sendiri, seperti saat Anda membuat variabel baru (y dalam kasus ini) dan menetapkannya ke nilai variabel lain (x), tempat lain di memori terpisah . Jadi, berdasarkan nilai, salin nilai variabel asli (a) ke dalam dua tempat terpisah di memori
Di sisi lain, dalam hal ini jika kita melewatkan variabel y dengan referensi, maka nilainya akan berubah menjadi 100, karena dalam referensi, fungsi mengambil variabel asli itu sendiri dan menggunakannya dalam fungsi daripada menggunakan salinan dari
Kata-kata Perpisahan
Saat membandingkan kedua fungsi, yaitu javascript pass by reference, pass by value, kita dapat melihat bahwa SEMUA objek berinteraksi dengan referensi di Javascript, jadi saat menyetel sama satu sama lain atau meneruskan ke suatu fungsi, semuanya menunjuk ke lokasi yang sama jadi saat Anda mengubah . Ini adalah perbedaan yang mencolok dibandingkan dengan nilai yang diteruskan, di mana fungsi nilai yang diteruskan menyalin nilai ke dalam dua titik terpisah dalam memori secara efektif menjadikannya entitas yang sepenuhnya terpisah meskipun satu awalnya ditetapkan sama dengan yang lain
Kelas adalah template untuk membuat objek. Mereka merangkum data dengan kode untuk mengerjakan data itu. Kelas di JS dibangun di atas prototipe tetapi juga memiliki beberapa sintaks dan semantik yang unik untuk kelas
Untuk contoh dan penjelasan lebih lanjut, lihat panduan Menggunakan kelas
Kelas sebenarnya adalah "fungsi khusus", dan sama seperti Anda dapat mendefinisikan ekspresi fungsi dan deklarasi fungsi, kelas dapat didefinisikan dalam dua cara. ekspresi kelas atau deklarasi kelas
// Declaration class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } // Expression; the class is anonymous but assigned to a variable const Rectangle = class { constructor(height, width) { this.height = height; this.width = width; } }; // Expression; the class has its own name const Rectangle = class Rectangle2 { constructor(height, width) { this.height = height; this.width = width; } };
Seperti ekspresi fungsi, ekspresi kelas mungkin anonim, atau memiliki nama yang berbeda dari variabel yang ditugaskan padanya. Namun, tidak seperti deklarasi fungsi, deklarasi kelas memiliki batasan yang sama seperti class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } 0 atau class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } 1 dan berperilaku seolah-olah
Badan kelas adalah bagian yang ada di dalam kurung kurawal class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } 2. Di sinilah Anda mendefinisikan anggota kelas, seperti metode atau konstruktor
Badan kelas dieksekusi dalam mode ketat bahkan tanpa direktif class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } 3
Elemen kelas dapat dicirikan oleh tiga aspek
- Baik. Pengambil, penyetel, metode, atau bidang
- Lokasi. Statis atau instan
- Visibilitas. Publik atau pribadi
Bersama-sama, mereka menambahkan hingga 16 kemungkinan kombinasi. Untuk membagi referensi secara lebih logis dan menghindari konten yang tumpang tindih, elemen yang berbeda diperkenalkan secara detail di halaman yang berbeda
Definisi metodeMetode contoh publik
pengambilPengambil instance publik
setterPembuat instance publik
Bidang kelas umumBidang instance publik
class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } _4Metode statis publik, pengambil, penyetel, dan bidang
Fitur kelas privatSegala sesuatu yang bersifat pribadi
Catatan. Fitur pribadi memiliki batasan bahwa semua nama properti yang dideklarasikan dalam kelas yang sama harus unik. Semua properti publik lainnya tidak memiliki batasan ini — Anda dapat memiliki beberapa properti publik dengan nama yang sama, dan yang terakhir menimpa yang lain. Ini adalah perilaku yang sama seperti di
Selain itu, ada dua sintaks elemen kelas khusus. dan , dengan referensi mereka sendiri
Konstruktor
Metode class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } 5 adalah metode khusus untuk membuat dan menginisialisasi objek yang dibuat dengan kelas. Hanya ada satu metode khusus dengan nama "konstruktor" di kelas — class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } 7 dilemparkan jika kelas berisi lebih dari satu kemunculan metode class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } 5
Konstruktor dapat menggunakan kata kunci class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } _9 untuk memanggil konstruktor kelas super
Anda dapat membuat properti instance di dalam konstruktor
class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } _
Alternatifnya, jika nilai properti instance Anda tidak bergantung pada argumen konstruktor, Anda dapat mendefinisikannya sebagai
Blok inisialisasi statis
Blok inisialisasi statis memungkinkan inisialisasi fleksibel, termasuk evaluasi pernyataan selama inisialisasi, sambil memberikan akses ke ruang lingkup pribadi
Beberapa blok statis dapat dideklarasikan, dan ini dapat diselingi dengan deklarasi bidang dan metode statis (semua item statis dievaluasi dalam urutan deklarasi)
Metode
Metode didefinisikan pada prototipe dari setiap instance kelas dan digunakan bersama oleh semua instance. Metode dapat berupa fungsi biasa, fungsi async, fungsi generator, atau fungsi generator async. Untuk informasi lebih lanjut, lihat definisi metode
class Rectangle { constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } *getSides() { yield this.height; yield this.width; yield this.height; yield this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100 console.log([...square.getSides()]); // [10, 10, 10, 10]
Metode dan bidang statis
Kata kunci class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } 4 mendefinisikan metode atau bidang statis untuk kelas. Properti statis (bidang dan metode) didefinisikan pada kelas itu sendiri, bukan pada setiap instance. Metode statis sering digunakan untuk membuat fungsi utilitas untuk aplikasi, sedangkan bidang statis berguna untuk cache, konfigurasi tetap, atau data lain yang tidak perlu direplikasi di seluruh instance
class Point { constructor(x, y) { this.x = x; this.y = y; } static displayName = "Point"; static distance(a, b) { const dx = a.x - b.x; const dy = a.y - b.y; return Math.hypot(dx, dy); } } const p1 = new Point(5, 5); const p2 = new Point(10, 10); p1.displayName; // undefined p1.distance; // undefined p2.displayName; // undefined p2.distance; // undefined console.log(Point.displayName); // "Point" console.log(Point.distance(p1, p2)); // 7.0710678118654755
Deklarasi lapangan
Dengan sintaks deklarasi bidang kelas, contohnya dapat ditulis sebagai
class Rectangle { height = 0; width; constructor(height, width) { this.height = height; this.width = width; } }
Bidang kelas mirip dengan properti objek, bukan variabel, jadi kami tidak menggunakan kata kunci seperti class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } 1 untuk mendeklarasikannya. Dalam JavaScript, gunakan sintaks pengidentifikasi khusus, jadi kata kunci pengubah seperti class Rectangle { constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } *getSides() { yield this.height; yield this.width; yield this.height; yield this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100 console.log([...square.getSides()]); // [10, 10, 10, 10] 2 dan class Rectangle { constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } *getSides() { yield this.height; yield this.width; yield this.height; yield this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100 console.log([...square.getSides()]); // [10, 10, 10, 10] 3 juga tidak boleh digunakan
Seperti yang terlihat di atas, field dapat dideklarasikan dengan atau tanpa nilai default. Kolom tanpa nilai default default ke class Rectangle { constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } *getSides() { yield this.height; yield this.width; yield this.height; yield this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100 console.log([...square.getSides()]); // [10, 10, 10, 10] 4. Dengan mendeklarasikan bidang di muka, definisi kelas menjadi lebih mendokumentasikan diri, dan bidang selalu ada, yang membantu pengoptimalan
Lihat kolom kelas publik untuk informasi lebih lanjut
Fitur kelas privat
Menggunakan bidang pribadi, definisi dapat disempurnakan seperti di bawah ini
class Rectangle { #height = 0; #width; constructor(height, width) { this.#height = height; this.#width = width; } }
Merupakan kesalahan untuk merujuk bidang pribadi dari luar kelas; . Dengan mendefinisikan hal-hal yang tidak terlihat di luar kelas, Anda memastikan bahwa pengguna kelas Anda tidak dapat bergantung pada internal, yang dapat berubah dari versi ke versi
Bidang pribadi hanya dapat dideklarasikan di muka dalam deklarasi bidang. Mereka tidak dapat dibuat nanti dengan menetapkannya, seperti yang dapat dilakukan oleh properti normal
Untuk informasi lebih lanjut, lihat fitur kelas privat
Kata kunci class Rectangle { constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } *getSides() { yield this.height; yield this.width; yield this.height; yield this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100 console.log([...square.getSides()]); // [10, 10, 10, 10] _5 digunakan dalam deklarasi kelas atau ekspresi kelas untuk membuat kelas sebagai anak dari konstruktor lain (baik kelas atau fungsi)
class Animal { constructor(name) { this.name = name; } speak() { console.log(`${this.name} makes a noise.`); } } class Dog extends Animal { constructor(name) { super(name); // call the super class constructor and pass in the name parameter } speak() { console.log(`${this.name} barks.`); } } const d = new Dog("Mitzie"); d.speak(); // Mitzie barks.
Jika ada konstruktor yang ada di subkelas, ia harus memanggil class Rectangle { constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } *getSides() { yield this.height; yield this.width; yield this.height; yield this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100 console.log([...square.getSides()]); // [10, 10, 10, 10] 6 terlebih dahulu sebelum menggunakan class Rectangle { constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } *getSides() { yield this.height; yield this.width; yield this.height; yield this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100 console.log([...square.getSides()]); // [10, 10, 10, 10] 7. Kata kunci class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } 9 juga dapat digunakan untuk memanggil metode kelas super yang sesuai
class Cat { constructor(name) { this.name = name; } speak() { console.log(`${this.name} makes a noise.`); } } class Lion extends Cat { speak() { super.speak(); console.log(`${this.name} roars.`); } } const l = new Lion("Fuzzy"); l.speak(); // Fuzzy makes a noise. // Fuzzy roars.
Ketika metode statis atau instance dipanggil tanpa nilai untuk class Rectangle { constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } *getSides() { yield this.height; yield this.width; yield this.height; yield this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100 console.log([...square.getSides()]); // [10, 10, 10, 10] 7, seperti dengan menugaskan metode ke variabel dan kemudian memanggilnya, nilai class Rectangle { constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } *getSides() { yield this.height; yield this.width; yield this.height; yield this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100 console.log([...square.getSides()]); // [10, 10, 10, 10] 7 akan menjadi class Rectangle { constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } *getSides() { yield this.height; yield this.width; yield this.height; yield this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100 console.log([...square.getSides()]); // [10, 10, 10, 10] 4 di dalam metode. Perilaku ini sama bahkan jika direktif class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } _3 tidak ada, karena kode di dalam tubuh class Point { constructor(x, y) { this.x = x; this.y = y; } static displayName = "Point"; static distance(a, b) { const dx = a.x - b.x; const dy = a.y - b.y; return Math.hypot(dx, dy); } } const p1 = new Point(5, 5); const p2 = new Point(10, 10); p1.displayName; // undefined p1.distance; // undefined p2.displayName; // undefined p2.distance; // undefined console.log(Point.displayName); // "Point" console.log(Point.distance(p1, p2)); // 7.0710678118654755 3 selalu dieksekusi dalam mode ketat
class Animal { speak() { return this; } static eat() { return this; } } const obj = new Animal(); obj.speak(); // the Animal object const speak = obj.speak; speak(); // undefined Animal.eat() // class Animal const eat = Animal.eat; eat(); // undefined
Jika kita menulis ulang di atas menggunakan sintaks berbasis fungsi tradisional dalam mode non-ketat, maka class Rectangle { constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } *getSides() { yield this.height; yield this.width; yield this.height; yield this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100 console.log([...square.getSides()]); // [10, 10, 10, 10] 7 panggilan metode secara otomatis terikat ke class Point { constructor(x, y) { this.x = x; this.y = y; } static displayName = "Point"; static distance(a, b) { const dx = a.x - b.x; const dy = a.y - b.y; return Math.hypot(dx, dy); } } const p1 = new Point(5, 5); const p2 = new Point(10, 10); p1.displayName; // undefined p1.distance; // undefined p2.displayName; // undefined p2.distance; // undefined console.log(Point.displayName); // "Point" console.log(Point.distance(p1, p2)); // 7.0710678118654755 5. Dalam mode ketat, nilai class Rectangle { constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } *getSides() { yield this.height; yield this.width; yield this.height; yield this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100 console.log([...square.getSides()]); // [10, 10, 10, 10] _7 tetap sebagai class Rectangle { constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } *getSides() { yield this.height; yield this.width; yield this.height; yield this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100 console.log([...square.getSides()]); // [10, 10, 10, 10] 4