在我的特殊情况下:
callback instanceof Function
要么
typeof callback == "function"
甚至重要,有什么区别?
额外资源:
JavaScript-Garden typeof vs instanceof
instanceof
自定义类型:var ClassFirst = function () {}; var ClassSecond = function () {}; var instance = new ClassFirst(); typeof instance; // object typeof instance == 'ClassFirst'; // false instance instanceof Object; // true instance instanceof ClassFirst; // true instance instanceof ClassSecond; // false
typeof
了内置的简单类型:'example string' instanceof String; // false typeof 'example string' == 'string'; // true 'example string' instanceof Object; // false typeof 'example string' == 'object'; // false true instanceof Boolean; // false typeof true == 'boolean'; // true 99.99 instanceof Number; // false typeof 99.99 == 'number'; // true function() {} instanceof Function; // true typeof function() {} == 'function'; // true
instanceof
了内建类型复杂:/regularexpression/ instanceof RegExp; // true typeof /regularexpression/; // object [] instanceof Array; // true typeof []; //object {} instanceof Object; // true typeof {}; // object
而最后一个有点棘手:
typeof null; // object
两者在功能上都相似,因为它们都返回类型信息,但我个人更喜欢,instanceof
因为它是比较实际类型而不是字符串.类型比较不容易出现人为错误,并且技术上更快,因为它比较内存中的指针而不是进行整个字符串比较.
使用typeof的一个很好的理由是变量可能未定义.
alert(typeof undefinedVariable); // alerts the string "undefined" alert(undefinedVariable instanceof Object); // throws an exception
使用instanceof的一个很好的理由是变量可能为null.
var myNullVar = null; alert(typeof myNullVar ); // alerts the string "object" alert(myNullVar instanceof Object); // alerts "false"
所以我认为这取决于您检查的数据类型.
为了弄清楚,你需要知道两个事实:
该的instanceof运算符测试是否原型属性一的构造函数中的任何地方出现的原型链的对象.在大多数情况下,这意味着该对象被创建通过使用此构造或者其后代的.但也可以通过Object.setPrototypeOf()
方法(ECMAScript 2015)或__proto__
属性(旧浏览器,不推荐使用)明确设置原型.但是,由于性能问题,不建议更改对象的原型.
因此,instanceof仅适用于对象.在大多数情况下,您不使用构造函数来创建字符串或数字.您可以.但你几乎从不这样做.
instanceof也无法检查,确切地使用了哪个构造函数来创建对象,但是返回true,即使object是从被检查的类派生的.在大多数情况下,这是期望的行为,但有时并非如此.所以你需要保持这种想法.
另一个问题是不同的范围具有不同的执行环境.这意味着它们具有不同的内置函数(不同的全局对象,不同的构造函数等).这可能会导致意外结果.
例如,[] instanceof window.frames[0].Array
将返回false
,因为Array.prototype !== window.frames[0].Array
和数组继承自前者.
此外,它不能用于未定义的值,因为它没有原型.
该typeof运算操作测试值是否属于六种基本类型之一:" 号码 "," 串 "," 布尔 "," 对象 "," 函数 "或" 不确定 ".字符串"object"属于所有对象(函数除外,它们是对象,但在typeof运算符中有自己的值),还有"null"值和数组(对于"null",它是一个bug,但是这个bug太旧了,所以它成为一个标准).它不依赖于构造函数,即使值未定义也可以使用.但它没有提供有关对象的任何细节.因此,如果您需要它,请转到instanceof.
现在让我们谈谈一件棘手的事情.如果使用构造函数创建基本类型怎么办?
let num = new Number(5); console.log(num instanceof Number); // print true console.log(typeof num); // print object num++; //num is object right now but still can be handled as number //and after that: console.log(num instanceof Number); // print false console.log(typeof num); // print number
看起来像魔术.但事实并非如此.它就是所谓的装箱(按对象包装原始值)和拆箱(从对象中提取包装的原始值).这种代码似乎"有点"脆弱.当然,您可以避免使用构造函数创建基本类型.但还有另一种可能的情况,拳击可能会打你.在基本类型上使用Function.call()或Function.apply()时.
function test(){ console.log(typeof this); } test.apply(5);
要避免这种情况,您可以使用严格模式:
function test(){ 'use strict'; console.log(typeof this); } test.apply(5);
upd: 自ECMAScript 2015以来,还有一个名为Symbol的类型,它有自己的typeof == "symbol".
console.log(typeof Symbol()); // expected output: "symbol"
您可以在MDN上阅读它:( 符号,typeof).
我在Safari 5和Internet Explorer 9中发现了一些非常有趣(读作"可怕")的行为.我在Chrome和Firefox中使用它非常成功.
if (typeof this === 'string') { doStuffWith(this); }
然后我在IE9中测试,它根本不起作用.大惊喜.但在Safari中,它是断断续续的!所以我开始调试,我发现Internet Explorer 总是返回false
.但最奇怪的是,Safari浏览器似乎是在做某种在它的JavaScript虚拟机优化的地方是true
在第一时间,但false
每次你打一次重装!
我的大脑几乎爆炸了.
所以现在我已经解决了这个问题:
if (this instanceof String || typeof this === 'string') doStuffWith(this.toString()); }
现在一切都很好.请注意,您可以调用"a string".toString()
它只返回字符串的副本,即
"a string".toString() === new String("a string").toString(); // true
所以我从现在开始都会使用它们.
instanceof
我认为,当它callback
是一个子类型时也有用Function
其他重大的实际差异:
// Boolean var str3 = true ; alert(str3); alert(str3 instanceof Boolean); // false: expect true alert(typeof str3 == "boolean" ); // true // Number var str4 = 100 ; alert(str4); alert(str4 instanceof Number); // false: expect true alert(typeof str4 == "number" ); // true