哪个最好用: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的可能的数据。
要说清楚,你需要知道两个事实:
- 如果一个对象是由给定的构造函数 创build的 , instanceof运算符返回true。 为此,它检查构造函数是否在对象的原型链中。
这意味着instanceof仅适用于对象。
这就是为什么它不用于检查原始types的原因。 在大多数情况下,您不使用构造函数来创buildstring或数字。 您可以。 但几乎从不做。
也不能检查,确切地说哪个构造函数被用来创build对象,但将返回true,即使对象是从被检查的类派生的。 在大多数情况下,这是所需的行为,但有时不是。 所以你需要保持这种心态。
另一个问题是不同的范围有不同的执行环境。 这意味着他们有不同的内置(不同的全局对象,不同的构造函数等)。 这可能会导致意想不到的结果。
例如, [] instanceof window.frames[0].Array
将返回false
,因为Array.prototype !== window.frames[0].Array
和数组inheritance前者。
此外,它不能用于未定义的值,因为它没有原型。
- 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
将返回false
而typeof "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
来检查函数的原因。
性能
在两种情况都适用的情况下, typeof
比instanceof
快。
取决于你的引擎, 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