Ini hanya pengetahuan pelengkap untuk semua penjelasan lainnya di sini - saya tidak menyarankan untuk digunakan di .constructor
mana-mana.
TL; DR: Dalam situasi di mana typeof
bukan merupakan pilihan, dan ketika Anda tahu bahwa Anda tidak peduli dengan rantai prototipe , Object.prototype.constructor
bisa menjadi alternatif yang lebih baik atau bahkan lebih baik daripada instanceof
:
x instanceof Y
x.constructor === Y
Sudah dalam standar sejak 1.1, jadi jangan khawatir tentang kompatibilitas mundur.
Muhammad Umer secara singkat menyebutkan ini dalam komentar di suatu tempat di sini juga. Ini bekerja pada semuanya dengan prototipe - jadi semuanya tidak null
atau undefined
:
// (null).constructor; // TypeError: null has no properties
// (undefined).constructor; // TypeError: undefined has no properties
(1).constructor; // function Number
''.constructor; // function String
([]).constructor; // function Array
(new Uint8Array(0)).constructor; // function Uint8Array
false.constructor; // function Boolean()
true.constructor; // function Boolean()
(Symbol('foo')).constructor; // function Symbol()
// Symbols work, just remember that this is not an actual constructor:
// new Symbol('foo'); //TypeError: Symbol is not a constructor
Array.prototype === window.frames.Array; // false
Array.constructor === window.frames.Array.constructor; // true
Selain itu, tergantung pada kasus penggunaan Anda, ini bisa menjadi jauh lebih cepat daripada instanceof
(alasannya adalah karena tidak perlu memeriksa seluruh rantai prototipe). Dalam kasus saya, saya membutuhkan cara cepat untuk memeriksa apakah suatu nilai adalah array yang diketik:
function isTypedArrayConstructor(obj) {
switch (obj && obj.constructor){
case Uint8Array:
case Float32Array:
case Uint16Array:
case Uint32Array:
case Int32Array:
case Float64Array:
case Int8Array:
case Uint8ClampedArray:
case Int16Array:
return true;
default:
return false;
}
}
function isTypedArrayInstanceOf(obj) {
return obj instanceof Uint8Array ||
obj instanceof Float32Array ||
obj instanceof Uint16Array ||
obj instanceof Uint32Array ||
obj instanceof Int32Array ||
obj instanceof Float64Array ||
obj instanceof Int8Array ||
obj instanceof Uint8ClampedArray ||
obj instanceof Int16Array;
}
https://run.perf.zone/view/isTypedArray-constructor-vs-instanceof-1519140393812
Dan hasilnya:
Chrome 64.0.3282.167 (64-bit, Windows)
Firefox 59.0b10 (64-bit, Windows)
Karena penasaran, saya melakukan benchmark cepat terhadap mainan typeof
; secara mengejutkan itu tidak berkinerja jauh lebih buruk, dan tampaknya bahkan lebih cepat di Chrome:
let s = 0,
n = 0;
function typeofSwitch(t) {
switch (typeof t) {
case "string":
return ++s;
case "number":
return ++n;
default:
return 0;
}
}
// note: no test for null or undefined here
function constructorSwitch(t) {
switch (t.constructor) {
case String:
return ++s;
case Number:
return ++n;
default:
return 0;
}
}
let vals = [];
for (let i = 0; i < 1000000; i++) {
vals.push(Math.random() <= 0.5 ? 0 : 'A');
}
https://run.perf.zone/view/typeof-vs-constructor-string-or-number-1519142623570
CATATAN: Urutan di mana fungsi yang terdaftar akan beralih di antara gambar!
Chrome 64.0.3282.167 (64-bit, Windows)
Firefox 59.0b10 (64-bit, Windows)
CATATAN: Urutan di mana fungsi yang terdaftar akan beralih di antara gambar!