哪个最好用:typeof或者instanceof?

在我的具体情况下:

callback instanceof Function 

要么

 typeof callback == "function" 

它甚至重要,有什么区别?

其他资源:

JavaScript-Garden typeof vs instanceof

对自定义types使用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 

对于简单的内置types使用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 

对于复杂的内置types使用instanceof

 /regularexpression/ instanceof RegExp; // true typeof /regularexpression/; //object [] instanceof Array; // true typeof []; //object {} instanceof Object; // true typeof {}; //object 

最后一个有点棘手:

 typeof null; //object 

两者在function上都是相似的,因为它们都返回types信息,但是我个人更喜欢instanceof因为它比较了实际types而不是string。 types比较不太容易出现人为错误,而且在技术上更快,因为它比较内存中的指针,而不是进行整个string比较。

使用typeof的一个很好的理由是如果variables可能是未定义的。

 alert(typeof undefinedVariable); // alerts the string "undefined" alert(undefinedVariable instanceof Object); // throws an exception 

使用instanceof的一个很好的理由是如果variables可能为空。

 var myNullVar = null; alert(typeof myNullVar ); // alerts the string "object" alert(myNullVar instanceof Object); // alerts "false" 

所以真的在我看来,这取决于你正在检查什么types的可能的数据。

要说清楚,你需要知道两个事实:

  1. 如果一个对象是由给定的构造函数 创build的instanceof运算符返回true。 为此,它检查构造函数是否在对象的原型链中。

这意味着instanceof仅适用于对象。

这就是为什么它不用于检查原始types的原因。 在大多数情况下,您不使用构造函数来创buildstring或数字。 您可以。 但几乎从不做。

也不能检查,确切地说哪个构造函数被用来创build对象,但将返回true,即使对象是从被检查的类派生的。 在大多数情况下,这是所需的行为,但有时不是。 所以你需要保持这种心态。

另一个问题是不同的范围有不同的执行环境。 这意味着他们有不同的内置(不同的全局对象,不同的构造函数等)。 这可能会导致意想不到的结果。

例如, [] instanceof window.frames[0].Array将返回false ,因为Array.prototype !== window.frames[0].Array和数组inheritance前者。
此外,它不能用于未定义的值,因为它没有原型。

  1. typeof运算符检查值是否属于六个基本types之一 :“ 数字 ”,“ string ”,“ 布尔 ”,“ 对象 ”,“ function ”或“ 未定义 ”。 string“对象”属于所有的对象(除了函数,它们是对象,但在typeof运算符中有它自己的值),还有“null”值和数组(对于“null”,这是一个错误,但是这个错误太旧了,所以它成为一个标准)。 它不依赖构造函数,即使值未定义也可以使用。 但是没有提供任何关于对象的细节。 所以,如果你需要它,去instanceof。

我在Safari 5和Internet Explorer 9中发现了一些非常有趣的(可怕的)行为。我在Chrome和Firefox上使用这个方法取得了巨大的成功。

 if (typeof this === 'string') { doStuffWith(this); } 

然后我在IE9中testing,它根本不工作。 大惊喜 但在Safari中,它是间歇性的! 所以我开始debugging,我发现Internet Explorer 总是返回false 。 但最奇怪的是,Safari浏览器似乎在JavaScript VM中进行了一些优化,但一次是true的,但每次重新加载时都是错误的!

我的大脑几乎爆炸了。

所以现在我已经解决了这个问题:

 if (this instanceof String || typeof this === 'string') doStuffWith(this.toString()); } 

现在一切都很好。 请注意,您可以调用"a string".toString() ,它只是返回string的副本,即

 "a string".toString() === new String("a string").toString(); // true 

所以我从现在开始使用

instanceof也适用于callback Function一个子types,我想

其他重要的实际差异:

 // 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 

JavaScript中的instanceof可以是片状的 – 我相信主要框架试图避免它的使用。 不同的窗口是它可以打破的方式之一 – 我相信阶级等级也会混淆它。

有更好的方法来testing一个对象是否是某种内置types(这通常是你想要的)。 创build实用function并使用它们:

 function isFunction(obj) { return typeof(obj) == "function"; } function isArray(obj) { return typeof(obj) == "object" && typeof(obj.length) == "number" && isFunction(obj.push); } 

等等。

instanceof不能用于原语,例如"foo" instanceof String将返回falsetypeof "foo" == "string"将返回true

另一方面, typeof可能不会做你想要的自定义对象(或类,无论你想调用它们)。 例如:

 function Dog() {} var obj = new Dog; typeof obj == 'Dog' // false, typeof obj is actually "object" obj instanceof Dog // true, what we want in this case 

只是碰巧函数是'函数'原语和'函数'的实例,这有点古怪,因为它不能像其他基本types那样工作。

 (typeof function(){} == 'function') == (function(){} instanceof Function) 

 (typeof 'foo' == 'string') != ('foo' instanceof String) 

我会build议使用原型的callback.isFunction()

他们已经找出了差异,你可以指望他们的理由。

我猜其他JS框架也有这样的事情。

我相信, instanceOf不能在其他窗口中定义的函数上工作。 他们的function是不同于你的window.Function

检查函数时,必须始终使用typeof

以下是区别:

 var f = Object.create(Function); console.log(f instanceof Function); //=> true console.log(typeof f === 'function'); //=> false f(); // throws TypeError: f is not a function 

这就是为什么一定不要使用instanceof来检查函数的原因。

性能

在两种情况都适用的情况下, typeofinstanceof快。

取决于你的引擎, typeof的性能差异可能在20%左右 。 ( 你的里程可能有所不同

这是Array的基准testing:

 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 

重大的实际区别:

 var str = 'hello word'; str instanceof String // false typeof str === 'string' // true 

不要问我为什么。

使用instanceof是因为如果你改变了类的名字,你会得到一个编译器错误。

来自严格的OO成长,我会去的

 callback instanceof Function 

string很容易出现我可怕的拼写或其他拼写错误。 另外我觉得它读得更好。

尽pipeinstanceof可能比typeof快一点,但我更喜欢第二个,因为这样一个可能的魔法:

 function Class() {}; Class.prototype = Function; var funcWannaBe = new Class; console.log(funcWannaBe instanceof Function); //true console.log(typeof funcWannaBe === "function"); //false funcWannaBe(); //Uncaught TypeError: funcWannaBe is not a function 

还有一种情况是,你只能用instanceof整理 – 它返回true或false。 用typeof你可以得到types的东西

 var newObj = new Object;//instance of Object var newProp = "I'm xgqfrms!" //define property var newFunc = function(name){//define function var hello ="hello, "+ name +"!"; return hello; } newObj.info = newProp;// add property newObj.func = newFunc;// add function console.log(newObj.info);// call function // I'm xgqfrms! console.log(newObj.func("ET"));// call function // hello, ET! console.log(newObj instanceof Object); //true console.log(typeof(newObj)); //"object" 

考虑到性能,最好使用typeof与典型的硬件,如果你创build一个循环1000万次迭代的脚本指令:typeof str =='string'将花费9ms,而'string'instanceof String将花费19ms