在JavaScript中使用toString()而不是构造函数

时间:2010-12-03 15:58:40

标签: javascript

这可能是一个愚蠢的问题,所以请坚持下去。

为什么我看到这么多的例子通过比较它的toString()和“[object Function]”来测试一个对象是否是一个函数?

例如:

function isFunction(obj) {
    return Object.prototype.toString.call(obj) == "[object Function]";
}

我们不能使用instanceof Functionobj.constructor === Function吗?这些不是跨浏览器兼容的吗?

这个似乎效率不高,但是呢?为什么呢?

2 个答案:

答案 0 :(得分:7)

简短回答是因为typeof /foo/是Webkit浏览器中的一个功能。 CMS有一个长期的解释@ jQuery's isFunction and InternetExplorer

instanceOf并不可靠,因为正如Zuriy指出的那样:

  

在多帧DOM环境中编写脚本时会出现问题。简而言之,在一个iframe中创建的Array对象不与另一个iframe中创建的数组共享[[Prototype]]。它们的构造函数是不同的对象,因此instanceof和构造函数检查都失败了:

Zuriy关于这个主题的文章@ http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/

取自文章的例子:

var iframe = document.createElement('iframe'); 
document.body.appendChild(iframe); 
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]  

// Boom! 
arr instanceof Array; // false  

// Boom! 
arr.constructor === Array; // false

答案 1 :(得分:1)

他们没有测试它的toString方法,他们在obj上调用Object的原型的toString方法将它转换为字符串。函数将'[object Function]'强制转换为字符串。

instanceof不可靠,也不是构造方法。在尝试访问其构造函数属性之前,构造函数需要检查obj是否为null - 我还猜测它比toString方法慢一点。