C'est juste une connaissance complémentaire à toutes les autres explications ici - je ne suggère pas d'utiliser .constructor
partout.
TL; DR: Dans les situations où ce typeof
n'est pas une option, et quand vous savez que vous ne vous souciez pas de la chaîne prototype , Object.prototype.constructor
peut être une alternative viable ou encore meilleure que instanceof
:
x instanceof Y
x.constructor === Y
Il est dans la norme depuis la version 1.1, donc ne vous inquiétez pas de la compatibilité descendante.
Muhammad Umer l'a brièvement mentionné dans un commentaire quelque part ici aussi. Il fonctionne sur tout avec un prototype - donc tout n'est pas null
ou 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
En outre, selon votre cas d'utilisation, cela peut être beaucoup plus rapide que instanceof
(la raison étant probablement qu'il n'a pas à vérifier la chaîne de prototype entière). Dans mon cas, j'avais besoin d'un moyen rapide pour vérifier si une valeur est un tableau typé:
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
Et les résultats:
Chrome 64.0.3282.167 (64 bits, Windows)
Firefox 59.0b10 (64 bits, Windows)
Par curiosité, j'ai fait une comparaison rapide de jouets contre typeof
; étonnamment, il ne fonctionne pas beaucoup moins bien, et il semble encore un peu plus rapide dans 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
REMARQUE: L'ordre dans lequel les fonctions sont répertoriées bascule entre les images!
Chrome 64.0.3282.167 (64 bits, Windows)
Firefox 59.0b10 (64 bits, Windows)
REMARQUE: L'ordre dans lequel les fonctions sont répertoriées bascule entre les images!