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

Eri*_*lin 13 javascript

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

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

例如:

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

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

似乎效率低下,但是呢?为什么?

med*_*iev 7

简短的回答是因为typeof /foo/是Webkit浏览器中的一个功能.CMS有很长的解释@ jQuery的isFunction和InternetExplorer

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

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

伟大的文章@ http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/由Zuriy就此主题发表.

从文章中取得的例子:

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
Run Code Online (Sandbox Code Playgroud)