Bisakah kita membuat kelas dalam javascript?

Dalam pemrograman berorientasi objek, kelas adalah templat kode program yang dapat diperluas untuk membuat objek, memberikan nilai awal untuk status (variabel anggota) dan implementasi perilaku (fungsi atau metode anggota)

Wikipedia

Dalam praktiknya, kita sering perlu membuat banyak objek dengan jenis yang sama, seperti pengguna, atau barang, atau apa pun

Seperti yang sudah kita ketahui dari bab Pembuat, operator "baru",

class User {

  constructor(name) {
    this.name = name;
  }

  sayHi() {
    alert(this.name);
  }

}

// Usage:
let user = new User("John");
user.sayHi();
8 dapat membantu dengan itu

Namun dalam JavaScript modern, ada konstruksi "kelas" yang lebih canggih, yang memperkenalkan fitur-fitur baru yang hebat yang berguna untuk pemrograman berorientasi objek

Sintaks dasarnya adalah

class MyClass {
  // class methods
  constructor() { .. }
  method1() { .. }
  method2() { .. }
  method3() { .. }
  ...
}
_

Kemudian gunakan

class User {

  constructor(name) {
    this.name = name;
  }

  sayHi() {
    alert(this.name);
  }

}

// Usage:
let user = new User("John");
user.sayHi();
_9 untuk membuat objek baru dengan semua metode yang terdaftar

Metode

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// proof: User is a function
alert(typeof User); // function
_0 dipanggil secara otomatis oleh
class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// proof: User is a function
alert(typeof User); // function
1, sehingga kita dapat menginisialisasi objek di sana

Sebagai contoh

class User {

  constructor(name) {
    this.name = name;
  }

  sayHi() {
    alert(this.name);
  }

}

// Usage:
let user = new User("John");
user.sayHi();

Ketika

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// proof: User is a function
alert(typeof User); // function
_2 dipanggil

  1. Objek baru dibuat
  2. class User {
      constructor(name) { this.name = name; }
      sayHi() { alert(this.name); }
    }
    
    // proof: User is a function
    alert(typeof User); // function
    _3 berjalan dengan argumen yang diberikan dan menugaskannya ke
    class User {
      constructor(name) { this.name = name; }
      sayHi() { alert(this.name); }
    }
    
    // proof: User is a function
    alert(typeof User); // function
    4

…Kemudian kita dapat memanggil metode objek, seperti

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// proof: User is a function
alert(typeof User); // function
5

Tidak ada koma di antara metode kelas

Jebakan umum untuk pengembang pemula adalah menempatkan koma di antara metode kelas, yang akan menghasilkan kesalahan sintaksis

Notasi di sini jangan disamakan dengan literal objek. Di dalam kelas, koma tidak diperlukan

Jadi, apa sebenarnya

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// proof: User is a function
alert(typeof User); // function
_6?

Mari ungkap keajaiban apa pun dan lihat apa sebenarnya kelas itu. Itu akan membantu dalam memahami banyak aspek kompleks

Dalam JavaScript, kelas adalah sejenis fungsi

Di sini, lihatlah

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// proof: User is a function
alert(typeof User); // function

Apa yang

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// proof: User is a function
alert(typeof User); // function
_7 benar-benar dilakukan adalah

  1. Membuat fungsi bernama
    class User {
      constructor(name) { this.name = name; }
      sayHi() { alert(this.name); }
    }
    
    // proof: User is a function
    alert(typeof User); // function
    _8, yang menjadi hasil deklarasi kelas. Kode fungsi diambil dari metode
    class User {
      constructor(name) { this.name = name; }
      sayHi() { alert(this.name); }
    }
    
    // proof: User is a function
    alert(typeof User); // function
    3 (diasumsikan kosong jika kita tidak menulis metode tersebut)
  2. Menyimpan metode kelas, seperti
    class User {
      constructor(name) { this.name = name; }
      sayHi() { alert(this.name); }
    }
    
    // class is a function
    alert(typeof User); // function
    
    // ...or, more precisely, the constructor method
    alert(User === User.prototype.constructor); // true
    
    // The methods are in User.prototype, e.g:
    alert(User.prototype.sayHi); // the code of the sayHi method
    
    // there are exactly two methods in the prototype
    alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
    _0, di
    class User {
      constructor(name) { this.name = name; }
      sayHi() { alert(this.name); }
    }
    
    // class is a function
    alert(typeof User); // function
    
    // ...or, more precisely, the constructor method
    alert(User === User.prototype.constructor); // true
    
    // The methods are in User.prototype, e.g:
    alert(User.prototype.sayHi); // the code of the sayHi method
    
    // there are exactly two methods in the prototype
    alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
    1

Setelah

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// class is a function
alert(typeof User); // function

// ...or, more precisely, the constructor method
alert(User === User.prototype.constructor); // true

// The methods are in User.prototype, e.g:
alert(User.prototype.sayHi); // the code of the sayHi method

// there are exactly two methods in the prototype
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
_2 objek dibuat, ketika kita memanggil metodenya, itu diambil dari prototipe, seperti yang dijelaskan dalam bab F. prototipe. Jadi objek memiliki akses ke metode kelas

Kita dapat mengilustrasikan hasil deklarasi

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// class is a function
alert(typeof User); // function

// ...or, more precisely, the constructor method
alert(User === User.prototype.constructor); // true

// The methods are in User.prototype, e.g:
alert(User.prototype.sayHi); // the code of the sayHi method

// there are exactly two methods in the prototype
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
_3 sebagai

Ini kode untuk mengintrospeksinya

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// class is a function
alert(typeof User); // function

// ...or, more precisely, the constructor method
alert(User === User.prototype.constructor); // true

// The methods are in User.prototype, e.g:
alert(User.prototype.sayHi); // the code of the sayHi method

// there are exactly two methods in the prototype
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi

Kadang-kadang orang mengatakan bahwa

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// proof: User is a function
alert(typeof User); // function
_6 adalah "gula sintaksis" (sintaks yang dirancang untuk membuat sesuatu lebih mudah dibaca, tetapi tidak memperkenalkan sesuatu yang baru), karena kita sebenarnya dapat mendeklarasikan hal yang sama tanpa menggunakan kata kunci
class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// proof: User is a function
alert(typeof User); // function
6 sama sekali

// rewriting class User in pure functions

// 1. Create constructor function
function User(name) {
  this.name = name;
}
// a function prototype has "constructor" property by default,
// so we don't need to create it

// 2. Add the method to prototype
User.prototype.sayHi = function() {
  alert(this.name);
};

// Usage:
let user = new User("John");
user.sayHi();

Hasil dari definisi ini hampir sama. Jadi, memang ada alasan mengapa

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// proof: User is a function
alert(typeof User); // function
_6 dapat dianggap sebagai gula sintaksis untuk mendefinisikan konstruktor bersama dengan metode prototipenya

Tetap saja, ada perbedaan penting

  1. Pertama, fungsi yang dibuat oleh

    class User {
      constructor(name) { this.name = name; }
      sayHi() { alert(this.name); }
    }
    
    // proof: User is a function
    alert(typeof User); // function
    _6 diberi label oleh properti internal khusus
    class User {
      constructor(name) { this.name = name; }
      sayHi() { alert(this.name); }
    }
    
    // class is a function
    alert(typeof User); // function
    
    // ...or, more precisely, the constructor method
    alert(User === User.prototype.constructor); // true
    
    // The methods are in User.prototype, e.g:
    alert(User.prototype.sayHi); // the code of the sayHi method
    
    // there are exactly two methods in the prototype
    alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
    8. Jadi tidak sepenuhnya sama dengan membuatnya secara manual

    Bahasa memeriksa properti itu di berbagai tempat. Misalnya, tidak seperti fungsi biasa, fungsi ini harus dipanggil dengan

    class User {
      constructor(name) { this.name = name; }
      sayHi() { alert(this.name); }
    }
    
    // proof: User is a function
    alert(typeof User); // function
    1

    class User {
      constructor() {}
    }
    
    alert(typeof User); // function
    User(); // Error: Class constructor User cannot be invoked without 'new'

    Juga, representasi string dari konstruktor kelas di sebagian besar mesin JavaScript dimulai dengan "kelas ..."

    class User {
      constructor() {}
    }
    
    alert(User); // class User { .. }

    Ada perbedaan lain, kita akan segera melihatnya

  2. Metode kelas tidak dapat dihitung. Definisi kelas menetapkan bendera

    // rewriting class User in pure functions
    
    // 1. Create constructor function
    function User(name) {
      this.name = name;
    }
    // a function prototype has "constructor" property by default,
    // so we don't need to create it
    
    // 2. Add the method to prototype
    User.prototype.sayHi = function() {
      alert(this.name);
    };
    
    // Usage:
    let user = new User("John");
    user.sayHi();
    0 ke
    // rewriting class User in pure functions
    
    // 1. Create constructor function
    function User(name) {
      this.name = name;
    }
    // a function prototype has "constructor" property by default,
    // so we don't need to create it
    
    // 2. Add the method to prototype
    User.prototype.sayHi = function() {
      alert(this.name);
    };
    
    // Usage:
    let user = new User("John");
    user.sayHi();
    1 untuk semua metode di
    // rewriting class User in pure functions
    
    // 1. Create constructor function
    function User(name) {
      this.name = name;
    }
    // a function prototype has "constructor" property by default,
    // so we don't need to create it
    
    // 2. Add the method to prototype
    User.prototype.sayHi = function() {
      alert(this.name);
    };
    
    // Usage:
    let user = new User("John");
    user.sayHi();
    2

    Itu bagus, karena jika kita

    // rewriting class User in pure functions
    
    // 1. Create constructor function
    function User(name) {
      this.name = name;
    }
    // a function prototype has "constructor" property by default,
    // so we don't need to create it
    
    // 2. Add the method to prototype
    User.prototype.sayHi = function() {
      alert(this.name);
    };
    
    // Usage:
    let user = new User("John");
    user.sayHi();
    3 atas sebuah objek, kita biasanya tidak menginginkan metode kelasnya

  3. Kelas selalu ________22______4. Semua kode di dalam konstruksi kelas secara otomatis dalam mode ketat

Selain itu, sintaks

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// proof: User is a function
alert(typeof User); // function
6 membawa banyak fitur lain yang akan kita jelajahi nanti

Sama seperti fungsi, kelas dapat didefinisikan di dalam ekspresi lain, diedarkan, dikembalikan, ditugaskan, dll

Berikut adalah contoh ekspresi kelas

let User = class {
  sayHi() {
    alert("Hello");
  }
};

Mirip dengan Ekspresi Fungsi Bernama, ekspresi kelas mungkin memiliki nama

Jika ekspresi kelas memiliki nama, itu hanya terlihat di dalam kelas

// "Named Class Expression"
// (no such term in the spec, but that's similar to Named Function Expression)
let User = class MyClass {
  sayHi() {
    alert(MyClass); // MyClass name is visible only inside the class
  }
};

new User().sayHi(); // works, shows MyClass definition

alert(MyClass); // error, MyClass name isn't visible outside of the class

Kita bahkan bisa membuat kelas secara dinamis “sesuai permintaan”, seperti ini

function makeClass(phrase) {
  // declare a class and return it
  return class {
    sayHi() {
      alert(phrase);
    }
  };
}

// Create a new class
let User = makeClass("Hello");

new User().sayHi(); // Hello

Sama seperti objek literal, kelas dapat menyertakan getter/setter, properti yang dihitung, dll

Berikut adalah contoh untuk

// rewriting class User in pure functions

// 1. Create constructor function
function User(name) {
  this.name = name;
}
// a function prototype has "constructor" property by default,
// so we don't need to create it

// 2. Add the method to prototype
User.prototype.sayHi = function() {
  alert(this.name);
};

// Usage:
let user = new User("John");
user.sayHi();
_6 diimplementasikan menggunakan
// rewriting class User in pure functions

// 1. Create constructor function
function User(name) {
  this.name = name;
}
// a function prototype has "constructor" property by default,
// so we don't need to create it

// 2. Add the method to prototype
User.prototype.sayHi = function() {
  alert(this.name);
};

// Usage:
let user = new User("John");
user.sayHi();
7

class User {

  constructor(name) {
    this.name = name;
  }

  sayHi() {
    alert(this.name);
  }

}

// Usage:
let user = new User("John");
user.sayHi();
0

Secara teknis, deklarasi kelas tersebut berfungsi dengan membuat getter dan setter di

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// class is a function
alert(typeof User); // function

// ...or, more precisely, the constructor method
alert(User === User.prototype.constructor); // true

// The methods are in User.prototype, e.g:
alert(User.prototype.sayHi); // the code of the sayHi method

// there are exactly two methods in the prototype
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
1

Berikut adalah contoh dengan nama metode yang dihitung menggunakan tanda kurung

// rewriting class User in pure functions

// 1. Create constructor function
function User(name) {
  this.name = name;
}
// a function prototype has "constructor" property by default,
// so we don't need to create it

// 2. Add the method to prototype
User.prototype.sayHi = function() {
  alert(this.name);
};

// Usage:
let user = new User("John");
user.sayHi();
9

class User {

  constructor(name) {
    this.name = name;
  }

  sayHi() {
    alert(this.name);
  }

}

// Usage:
let user = new User("John");
user.sayHi();
_1

Fitur seperti itu mudah diingat, karena mirip dengan objek literal

Browser lama mungkin memerlukan polyfill

Bidang kelas adalah tambahan terbaru untuk bahasa

Sebelumnya, kelas kami hanya memiliki metode

"Bidang kelas" adalah sintaks yang memungkinkan untuk menambahkan properti apa pun

Misalnya, mari tambahkan properti

class User {
  constructor() {}
}

alert(typeof User); // function
User(); // Error: Class constructor User cannot be invoked without 'new'
_0 ke
class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// class is a function
alert(typeof User); // function

// ...or, more precisely, the constructor method
alert(User === User.prototype.constructor); // true

// The methods are in User.prototype, e.g:
alert(User.prototype.sayHi); // the code of the sayHi method

// there are exactly two methods in the prototype
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
3

class User {

  constructor(name) {
    this.name = name;
  }

  sayHi() {
    alert(this.name);
  }

}

// Usage:
let user = new User("John");
user.sayHi();
_2

Jadi, kami hanya menulis "=" di deklarasi, dan hanya itu

Perbedaan penting dari bidang kelas adalah bahwa mereka ditetapkan pada objek individual, bukan

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// class is a function
alert(typeof User); // function

// ...or, more precisely, the constructor method
alert(User === User.prototype.constructor); // true

// The methods are in User.prototype, e.g:
alert(User.prototype.sayHi); // the code of the sayHi method

// there are exactly two methods in the prototype
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
1

class User {

  constructor(name) {
    this.name = name;
  }

  sayHi() {
    alert(this.name);
  }

}

// Usage:
let user = new User("John");
user.sayHi();
_3

Kami juga dapat menetapkan nilai menggunakan ekspresi dan pemanggilan fungsi yang lebih kompleks

class User {

  constructor(name) {
    this.name = name;
  }

  sayHi() {
    alert(this.name);
  }

}

// Usage:
let user = new User("John");
user.sayHi();
_4

Seperti yang ditunjukkan dalam bab Fungsi pengikatan fungsi dalam JavaScript memiliki

class User {
  constructor() {}
}

alert(typeof User); // function
User(); // Error: Class constructor User cannot be invoked without 'new'
3 dinamis. Itu tergantung pada konteks panggilan

Jadi jika metode objek diedarkan dan dipanggil dalam konteks lain,

class User {
  constructor() {}
}

alert(typeof User); // function
User(); // Error: Class constructor User cannot be invoked without 'new'
3 tidak akan menjadi referensi ke objeknya lagi

Misalnya, kode ini akan menampilkan

class User {
  constructor() {}
}

alert(typeof User); // function
User(); // Error: Class constructor User cannot be invoked without 'new'
5

class User {

  constructor(name) {
    this.name = name;
  }

  sayHi() {
    alert(this.name);
  }

}

// Usage:
let user = new User("John");
user.sayHi();
5

Masalahnya disebut "kehilangan

class User {
  constructor() {}
}

alert(typeof User); // function
User(); // Error: Class constructor User cannot be invoked without 'new'
3"

Ada dua pendekatan untuk memperbaikinya, seperti yang dibahas di bab Pengikatan fungsi

  1. Berikan fungsi pembungkus, seperti
    class User {
      constructor() {}
    }
    
    alert(typeof User); // function
    User(); // Error: Class constructor User cannot be invoked without 'new'
    7
  2. Ikat metode ke objek, e. g. dalam konstruktor

Bidang kelas menyediakan sintaks lain yang cukup elegan

class User {

  constructor(name) {
    this.name = name;
  }

  sayHi() {
    alert(this.name);
  }

}

// Usage:
let user = new User("John");
user.sayHi();
_6

Bidang kelas

class User {
  constructor() {}
}

alert(typeof User); // function
User(); // Error: Class constructor User cannot be invoked without 'new'
8 dibuat per objek, ada fungsi terpisah untuk setiap objek
class User {
  constructor() {}
}

alert(typeof User); // function
User(); // Error: Class constructor User cannot be invoked without 'new'
9, dengan
class User {
  constructor() {}
}

alert(typeof User); // function
User(); // Error: Class constructor User cannot be invoked without 'new'
3 di dalamnya merujuk objek itu. Kita dapat melewati
class User {
  constructor() {}
}

alert(User); // class User { .. }
1 di mana saja, dan nilai
class User {
  constructor() {}
}

alert(typeof User); // function
User(); // Error: Class constructor User cannot be invoked without 'new'
3 akan selalu benar

Itu sangat berguna di lingkungan browser, untuk event listener

Sintaks kelas dasar terlihat seperti ini

class User {

  constructor(name) {
    this.name = name;
  }

  sayHi() {
    alert(this.name);
  }

}

// Usage:
let user = new User("John");
user.sayHi();
_7

class User {
  constructor() {}
}

alert(User); // class User { .. }
3 secara teknis adalah fungsi (salah satu yang kami berikan sebagai
class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// proof: User is a function
alert(typeof User); // function
3), sedangkan metode, pengambil dan penyetel ditulis ke
class User {
  constructor() {}
}

alert(User); // class User { .. }
5

Bisakah Anda membuat kelas dalam JavaScript?

Untuk membuat kelas, Anda menggunakan kata kunci class . Di dalam kelas, kami membuat fungsi konstruktor, yang mendefinisikan semua properti awal. Berbeda dengan objek kita di atas, class adalah template untuk membuat objek. Semua properti dalam fungsi konstruktor akan ditambahkan secara otomatis ke objek baru Anda.

Mengapa kelas tidak digunakan dalam JavaScript?

Objek yang didefinisikan dengan kelas harus secara eksplisit menggunakan kata kunci 'ini' . Jika Anda meneruskan metode kelas ke panggilan balik, Anda bisa mengalami masalah yang mengikat. Inilah mengapa Anda akan melihat banyak kode di mana metode harus terikat dengan konteks yang benar.

Bagaimana cara mengatur kelas dalam JavaScript?

Untuk mengubah semua kelas untuk suatu elemen. getElementById("ElementSaya"). className = "MyClass"; (Anda dapat menggunakan daftar yang dibatasi spasi untuk menerapkan beberapa kelas. )

Haruskah saya membuat kelas dalam JavaScript?

Dalam JavaScript, Anda tidak . Anda dapat menulis program apa pun yang Anda inginkan tanpa menggunakan kelas atau kata kunci this ever. Memang, sintaks kelas agak baru untuk JavaScript, dan kode berorientasi objek ditulis dengan fungsi sebelumnya. Sintaks kelas hanyalah gula sintaksis di atas pendekatan berbasis fungsi untuk OOP.