Kelas bawaan seperti Array, Peta, dan lainnya juga dapat diperluas.
Misalnya, di sini PowerArray
mewarisi dari Array
asli :
// menambahkan satu metode lagi ke dalamnya (bisa melakukan lebih banyak) kelas PowerArray memperluas Array { isEmpty() { kembalikan ini.panjang === 0; } } biarkan arr = PowerArray baru(1, 2, 5, 10, 50); waspada(arr.isEmpty()); // PALSU biarkan filteredArr = arr.filter(item => item >= 10); peringatan(filteredArr); // 10, 50 waspada(filteredArr.isEmpty()); // PALSU
Harap perhatikan hal yang sangat menarik. Metode bawaan seperti filter
, map
, dan lainnya – mengembalikan objek baru dengan tipe yang sama persis dengan PowerArray
. Implementasi internalnya menggunakan properti constructor
objek untuk itu.
Pada contoh di atas,
arr.konstruktor === PowerArray
Saat arr.filter()
dipanggil, secara internal ia akan membuat array hasil baru menggunakan arr.constructor
, bukan Array
dasar. Itu sebenarnya sangat keren, karena kita bisa terus menggunakan metode PowerArray
lebih jauh lagi untuk mendapatkan hasilnya.
Terlebih lagi, kita dapat menyesuaikan perilaku itu.
Kita dapat menambahkan pengambil statis khusus Symbol.species
ke kelas. Jika ada, ia harus mengembalikan konstruktor yang akan digunakan JavaScript secara internal untuk membuat entitas baru di map
, filter
, dan seterusnya.
Jika kita ingin metode bawaan seperti map
atau filter
mengembalikan array reguler, kita dapat mengembalikan Array
dalam Symbol.species
, seperti di sini:
kelas PowerArray memperluas Array { isEmpty() { kembalikan ini.panjang === 0; } // metode bawaan akan menggunakan ini sebagai konstruktor get statis [Simbol.spesies]() { kembalikan Array; } } biarkan arr = PowerArray baru(1, 2, 5, 10, 50); waspada(arr.isEmpty()); // PALSU // filter membuat array baru menggunakan arr.constructor[Symbol.species] sebagai konstruktor biarkan filteredArr = arr.filter(item => item >= 10); // filteredArr bukan PowerArray, melainkan Array waspada(filteredArr.isEmpty()); // Kesalahan: filteredArr.isEmpty bukan sebuah fungsi
Seperti yang Anda lihat, sekarang .filter
mengembalikan Array
. Jadi fungsionalitas yang diperluas tidak diteruskan lebih jauh.
Koleksi lain bekerja dengan cara yang sama
Koleksi lain, seperti Map
dan Set
, berfungsi sama. Mereka juga menggunakan Symbol.species
.
Objek bawaan memiliki metode statisnya sendiri, misalnya Object.keys
, Array.isArray
, dll.
Seperti yang telah kita ketahui, kelas-kelas asli saling memperluas. Misalnya, Array
memperluas Object
.
Biasanya, ketika satu kelas memperluas kelas lainnya, metode statis dan non-statis akan diwarisi. Hal itu dijelaskan secara menyeluruh di artikel Sifat dan metode statis.
Namun kelas bawaan merupakan pengecualian. Mereka tidak mewarisi statika satu sama lain.
Misalnya, Array
dan Date
mewarisi dari Object
, sehingga instance mereka memiliki metode dari Object.prototype
. Namun Array.[[Prototype]]
tidak mereferensikan Object
, jadi tidak ada, misalnya, metode statis Array.keys()
(atau Date.keys()
).
Berikut struktur gambar untuk Date
dan Object
:
Seperti yang Anda lihat, tidak ada hubungan antara Date
dan Object
. Mereka independen, hanya Date.prototype
yang mewarisi dari Object.prototype
.
Itu adalah perbedaan penting dalam pewarisan antara objek bawaan dibandingkan dengan apa yang kita dapatkan dengan extends
.