JavaScript menggunakan warisan prototipe secara default. Walaupun tidak ada konsep kelas, namun fungsinya dapat berperan sebagai konstruktor. Konstruktor yang dikombinasikan dengan this dan new dapat membangun kelas mirip Java. Oleh karena itu, JavaScript dapat meniru warisan berbasis kelas dengan memperluas dirinya sendiri.
JavaScript, seperti bahasa berorientasi objek lainnya, menggunakan referensi untuk tipe objek. Variabel yang menampung objek hanyalah sebuah alamat, sedangkan tipe data dasarnya adalah nilainya. Saat menyimpan objek pada prototipe, mungkin ada beberapa kendala.
Mari kita lihat contoh pertama terlebih dahulu
Copy kode kodenya sebagai berikut:
var buat = fungsi() {
fungsi Fn() {}
fungsi kembali (induk) {
Fn.prototype = induk
kembalikan Fn baru
}
}()
var induk = {
nama: 'jack',
usia: 30,
sudah menikah: salah
}
var anak = buat(induk)
console.log(anak)
Fungsi alat buat mengimplementasikan pewarisan prototipe dasar. Setiap kali pembuatan dipanggil, objek baru akan disalin berdasarkan objek induk. Di sini induk memiliki tiga atribut, yang semuanya merupakan tipe data dasar: string, angka, dan Boolean.
Sekarang ubah anak untuk melihat apakah itu akan mempengaruhi induknya.
Copy kode kodenya sebagai berikut:
anak.nama = 'lily'
anak.usia = 20,
anak.isMarried = benar
console.log(anak)
console.log(induk)
Hasilnya adalah sebagai berikut
Artinya, memodifikasi anak tidak akan mempengaruhi orang tua.
Mari kita lihat contoh lainnya
Copy kode kodenya sebagai berikut:
var buat = fungsi() {
fungsi Fn() {}
fungsi kembali (induk) {
Fn.prototype = induk
kembalikan Fn baru
}
}()
var induk = {
data: {
nama: 'jack',
usia: 30,
sudah menikah: salah
},
bahasa: ['Jawa']
}
var anak = buat(induk)
anak.data.nama = 'lily'
anak.data.usia = 20
anak.data.isMarried = benar
anak.bahasa.push('javascript')
console.dir(anak)
console.dir(induk)
Perhatikan bahwa dua atribut induk di sini, data dan bahasa, keduanya merupakan tipe referensi, yang satu adalah objek dan yang lainnya adalah array. Anak tetap mewarisi dari induknya, kemudian anak tersebut dimodifikasi
Seperti yang Anda lihat, induknya juga telah dimodifikasi saat ini, dan nama, usia, dll. dari anaknya juga sama. Ini adalah sesuatu yang harus diperhatikan ketika menggunakan warisan prototipe.
Cara yang lebih baik untuk menggunakan warisan adalah:
1. Atribut data mengadopsi pewarisan kelas (tergantung pada ini), sehingga atribut tersebut juga dapat dikonfigurasi melalui parameter saat baru
2. Metode ini mengadopsi pewarisan prototipe, yang dapat menghemat memori. Pada saat yang sama, mengganti metode berdasarkan subkelas tidak akan mempengaruhi kelas induk.
Berikut fungsi alat tulis yang memenuhi dua poin di atas.
Copy kode kodenya sebagai berikut:
/**
* @param {String} nama kelas
* @param {String/Fungsi} superCls
* @param {Fungsi} pabrik
*/
fungsi $kelas(nama, superClass, pabrik) {
if (superClass === '') superClass = Objek
fungsi kelas() {
if (typeof this.init === 'fungsi') {
this.init.apply(ini, argumen)
}
}
var p = clazz.prototype = superCl baru
clazz.prototype.constructor = clazz
clazz.prototype.className = nama kelas
var supr = superCls.prototipe
jendela[namakelas] = clazz
pabrik.panggilan(p, supr)
}
Saat menempatkan tipe objek pada prototipe kelas induk, berhati-hatilah saat subkelas memodifikasinya. Dalam hal ini, semua instance subkelas yang mewarisi dari kelas induk akan diubah. Dan bug yang disebabkan oleh hal ini sangat sulit ditemukan.
API baru telah ditambahkan ke ES5 untuk mengimplementasikan pewarisan prototipe: Object.create. Anda dapat menggunakannya untuk menggantikan fungsi create yang diterapkan sendiri di atas, sebagai berikut
Copy kode kodenya sebagai berikut:
var induk = {
nama: 'jack',
usia: 30,
sudah menikah: salah
}
var anak = Objek.buat(induk)
console.log(anak)