这只是对这里所有其他解释的补充知识 - 我不建议在任何地方使用.constructor。
TL;DR:在typeof 不是一个选项的情况下,以及当你知道你不关心原型链时 strong>,Object.prototype.constructor 可能是比instanceof 更可行甚至更好的替代方案:
x instanceof Y
x.constructor === Y
它从 1.1 开始就已成为标准,因此无需担心向后兼容性。
Muhammad Umer 也在此处某处的评论中简要提到了这一点。它适用于所有带有原型的东西——所以不是null 或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
此外,根据您的用例,它可能比instanceof 快很多(原因可能是它不必检查整个原型链)。就我而言,我需要一种快速的方法来检查一个值是否是一个类型化数组:
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
结果:
Chrome 64.0.3282.167(64 位,Windows)
Firefox 59.0b10(64 位,Windows)
出于好奇,我对typeof 做了一个快速的玩具基准测试;令人惊讶的是,它的性能并没有差多少,而且在 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
注意:功能的列出顺序在图像之间切换!
Chrome 64.0.3282.167(64 位,Windows)
Firefox 59.0b10(64 位,Windows)
注意:功能的列出顺序在图像之间切换!