Bisakah kita melewatkan kelas sebagai parameter dalam javascript?

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); // 100 

Penjelasan 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 metode

Metode contoh publik

pengambil

Pengambil instance publik

setter

Pembuat instance publik

Bidang kelas umum

Bidang instance publik

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}
_4

Metode statis publik, pengambil, penyetel, dan bidang

Fitur kelas privat

Segala 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

Bisakah Anda melewatkan kelas sebagai parameter dalam JavaScript?

Ya, Anda bisa . Tetapi kelas itu sendiri tidak memiliki nilai apa pun dan itu hanya sebuah skema. Anda perlu membuat instance (instantiate) dari kelas dan meneruskannya sebagai argumen ke metode (fungsi) apa pun.

Bagaimana cara melewatkan nama kelas sebagai parameter dalam JavaScript?

Sintaksnya adalah sebagai berikut. var elemen = dokumen. getElementsByClassName(name); Di sini “nama” adalah nama kelas yang ingin Anda temukan dan “elemen” adalah variabel yang berisi larik elemen.

Bisakah kita melewatkan objek kelas sebagai argumen fungsi dalam JavaScript?

Kita dapat meneruskan objek ke fungsi JavaScript, tetapi argumen harus memiliki nama yang sama dengan nama properti Object .

Bisakah kelas menjadi parameter fungsi?

class adalah kata kunci yang hanya digunakan* untuk memperkenalkan definisi kelas. Saat Anda mendeklarasikan instance kelas baru sebagai objek lokal atau sebagai parameter fungsi, Anda hanya menggunakan nama kelas (yang harus berada dalam cakupan) dan bukan kata kunci class itu sendiri.