在我的特殊情况下:
callback instanceof Function
or
typeof callback == "function"
这有关系吗,有什么区别?
额外的资源:
花园typeof vs instanceof
在我的特殊情况下:
callback instanceof Function
or
typeof callback == "function"
这有关系吗,有什么区别?
额外的资源:
花园typeof vs instanceof
当前回答
还有一种情况是你只能用instanceof进行排序——它返回true或false。使用typeof你可以得到typeof提供的东西
其他回答
我认为,当callback是Function的子类型时,instanceof也可以工作
性能
在两者都适用的情况下,Typeof比instanceof更快。
根据您的引擎,有利于typeof的性能差异可能在20%左右。(您的里程可能有所不同)
下面是Array的基准测试:
var subject = new Array();
var iterations = 10000000;
var goBenchmark = function(callback, iterations) {
var start = Date.now();
for (i=0; i < iterations; i++) { var foo = callback(); }
var end = Date.now();
var seconds = parseFloat((end-start)/1000).toFixed(2);
console.log(callback.name+" took: "+ seconds +" seconds.");
return seconds;
}
// Testing instanceof
var iot = goBenchmark(function instanceofTest(){
(subject instanceof Array);
}, iterations);
// Testing typeof
var tot = goBenchmark(function typeofTest(){
(typeof subject == "object");
}, iterations);
var r = new Array(iot,tot).sort();
console.log("Performance ratio is: "+ parseFloat(r[1]/r[0]).toFixed(3));
结果
instanceofTest took: 9.98 seconds.
typeofTest took: 8.33 seconds.
Performance ratio is: 1.198
这只是对这里所有其他解释的补充知识——我不建议在所有地方都使用.constructor。
TL;DR:在typeof不是一个选项的情况下,并且当你知道你不关心原型链的时候,Object.prototype.constructor可以是一个可行的甚至比instanceof更好的选择:
x instanceof Y
x.constructor === Y
它从1.1开始就在标准中了,所以不用担心向后兼容性。
Muhammad Umer也在这里的一个评论中简要地提到了这一点。它适用于所有有原型的东西——所以所有不是null或未定义的东西:
// (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)
注意:函数列表的顺序在图像之间切换!
两者在功能上相似,因为它们都返回类型信息,但我个人更喜欢instanceof,因为它比较的是实际类型而不是字符串。类型比较不容易出现人为错误,而且技术上更快,因为它比较内存中的指针,而不是整个字符串的比较。
typeof:根据MDN文档,typeof是一个一元操作符,返回指示未求值操作数类型的字符串。
在字符串原语和字符串对象的情况下,typeof返回如下:
const a = "I'm a string primitive";
const b = new String("I'm a String Object");
typeof a; --> returns 'string'
typeof b; --> returns 'object'
Instanceof:是一个二进制操作符,接受一个对象和一个构造函数。它返回一个布尔值,指示对象的原型链中是否有给定的构造函数。
当应用于上面的string实例时,并与string进行比较,它的行为如下:
const a = "I'm a string primitive";
const b = new String("I'm a String Object");
a instanceof String; --> returns false
b instanceof String; --> returns true
参考:https://bambielli.com/til/2017-06-18-typeof-vs-instanceof/