Kita tahu bahwa operator instanceof digunakan untuk memeriksa apakah suatu objek merupakan turunan dari konstruktor. Berbagai skenario yang mengembalikan nilai true tercantum di bawah ini.
1. Objek obj dibuat melalui Konstruktor baru, maka objek instance dari Konstruktor adalah true
Copy kode kodenya sebagai berikut:
fungsi Orang(n, a) {
ini.nama = n;
ini.umur = a;
}
var p = Orang baru('John Backus', 82);
console.log(p instanceof Orang); // benar
2. Jika ada hubungan pewarisan, instance dari subkelas dan kelas induk juga akan mengembalikan nilai true.
Copy kode kodenya sebagai berikut:
fungsi A(){}
fungsi B(){}
B.prototipe = new A(); // B mewarisi dari A
var b = baru B();
console.log(b contoh A); // benar
3. Karena Object adalah kelas root, semua kelas khusus lainnya mewarisinya, sehingga instance dari Object dari konstruktor mana pun mengembalikan nilai true.
Copy kode kodenya sebagai berikut:
fungsi A() {}
var a = baru A();
console.log(sebuah instance dari Objek); // benar
var str = String baru('halo');
console.log(str instanceof Objek); // benar
var nomor = Nomor baru(1);
console.log(jumlah instanceObjek); // benar
Bahkan konstruktornya sendiri
Copy kode kodenya sebagai berikut:
fungsi A() {}
console.log(Sebuah instance dari Objek); // benar
console.log(String instance dari Objek); // benar
console.log(Nomor instanceObjek); // benar
4. Semua fungsi instanceof konstruktor mengembalikan nilai true
Copy kode kodenya sebagai berikut:
fungsi A() {}
console.log(Fungsi instanceof); // benar
console.log(String instanceof Fungsi); // benar
console.log(Nomor instanceof Function); // benar
Empat poin di atas dirangkum dalam satu kalimat: Jika sebuah instance dibuat oleh kelas atau subkelas tertentu, maka instanceof mengembalikan nilai true. Atau jika prototipe konstruktor tertentu ada pada rantai prototipe internal objek obj, maka nilai true dikembalikan. Artinya, hasil instanceof tidak mempunyai hubungan langsung dengan konstruktor itu sendiri. Hal ini umum terjadi di banyak bahasa.
Kelas Person didefinisikan di Java, dan instance p mengembalikan nilai true untuk Person dan Object.
Copy kode kodenya sebagai berikut:
kelas Orang {
nama String publik;
usia publik;
Orang (String n, int a) {
ini.nama = nama;
ini.umur = a;
}
public static void main(String[] args) {
Orang p = Orang baru("John Backus", 82);
Sistem.keluar.println(p instanceof Person); // benar
System.out.println(p instanceof Objek); // benar
}
}
Jika ada hubungan pewarisan di Java, maka kelas induk instanceof dari subkelas tersebut juga mengembalikan nilai true.
Copy kode kodenya sebagai berikut:
// kelas induk
kelas Orang {
nama String publik;
usia publik;
Orang (String n, int a) {
nama = nama;
umur = a;
}
}
// subkelas
kelas publik Man memperluas Person{
universitas negeri String;
Manusia(String n, int a, String s) {
super(n, a);
universitas = s;
}
public static void main(String[] args) {
Man mm = New Man("John Resig", 29, "PKU");
Sistem.keluar.println(mm instanceof Man); // benar
System.out.println(mm instanceof Person); // juga benar
}
}
Mengetahui hal ini, performa di JS berikut ini tidak mengejutkan
Copy kode kodenya sebagai berikut:
//Tentukan dua konstruktor
fungsi A(){}
fungsi B(){}
A.prototipe = B.prototipe = {a: 1};
//Buat masing-masing dua instance konstruktor berbeda
var a = baru A();
var b = baru B();
console.log(contoh B); // benar
console.log(b contoh A); // benar
Kita melihat bahwa a dan b dibuat dengan A dan B masing-masing, tetapi turunan dari B dan b turunan dari A keduanya benar. Artinya, meskipun a tidak dibuat dengan konstruktor B, ia tetap mengembalikan nilai true. Karena B.prototype ada pada rantai prototipe internal a.
Karena karakteristik bahasa JS yang dinamis, prototipe dapat dimodifikasi saat runtime, sehingga tidak mengherankan jika hasil berikut salah. Karena A.prototype tidak lagi berada dalam rantai prototipe internal a, rantai tersebut terputus.
Copy kode kodenya sebagai berikut:
fungsi A(){}
var a = baru A();
A.prototype = {}; // Memodifikasi prototipe secara dinamis, harap diperhatikan bahwa ini harus dilakukan setelah membuat a
console.log(sebuah instance dari A); // false
Perhatikan bahwa penulisan ini juga melanggar poin pertama yang dirangkum di atas: objek obj dibuat melalui Konstruktor baru, maka objek instanceof Constructor adalah true
Sebenarnya dalam standar ECMAScript (tunduk pada 5.1), implementasi internal instanceof akan memanggil metode internal [[HasInstance]] konstruktor, yang dijelaskan sebagai berikut
Jika F adalah objek fungsi, ketika F(V) dijalankan, langkah-langkah berikut akan terjadi:
1. Jika operan kiri V dari instanceof bukan tipe objek, kembalikan false secara langsung.
Copy kode kodenya sebagai berikut:
var a, b = 1, c = benar, d = 'halo';
console.log(a instanceof Object); // false di sini nilainya tidak ditentukan
console.log(b instanceObjek); // salah
console.log(c instanceof Objek); // salah
console.log(d contoh Objek); // salah
2/3. Dapatkan atribut prototipe konstruktor F. Jika ini bukan tipe objek, pengecualian TypeError harus dilempar.
Copy kode kodenya sebagai berikut:
fungsi A(){}
A.prototype = 1; // Atur prototipe A ke tipe non-objek
var a = baru A();
console.log(sebuah instance dari A);
Permintaan pengecualian yang diberikan oleh setiap browser berbeda.
Firefox18:
Chrome24:
Safari6:
Opera12:
IE10:
4. Terus jalankan logika berikut: setel V ke V prototipe internal, kembalikan false jika V bernilai nol, dan kembalikan true jika V dan O menunjuk ke objek yang sama.