Javascript 在isPlainObject函数中,宿主对象是否应算作普通对象?
我一直在测试不同浏览器上不同库的isPlainObject函数 在广泛的对象上测试了4种不同的(代码方面的)isPlainObject函数:Javascript 在isPlainObject函数中,宿主对象是否应算作普通对象?,javascript,jquery,javascript-objects,lodash,Javascript,Jquery,Javascript Objects,Lodash,我一直在测试不同浏览器上不同库的isPlainObject函数 在广泛的对象上测试了4种不同的(代码方面的)isPlainObject函数: jquery 洛达斯 实用程序(我正在处理的库) 备选方案,在下面的评论中建议 以上四个版本在Chrome v23.0.1271.95到Chrome v25.0.1364.160、FireFox V19.0和Opera v12.14上都有所不同,但该工具在所有浏览器上至少对这些对象给出相同的false响应 在Chrome上运行时 Failed to a
- jquery
- 洛达斯
- 实用程序(我正在处理的库)
- 备选方案,在下面的评论中建议
Failed to agree: JSON - jquery: true - utility: false - lodash: true - alt: false
Failed to agree: Math - jquery: true - utility: false - lodash: true - alt: false
Failed to agree: top - jquery: false - utility: false - lodash: true - alt: true
Failed to agree: parent - jquery: false - utility: false - lodash: true - alt: true
- 正确的是例程认为对象是简单的,而错误不是简单的
检查对象是否为普通对象(使用“{}”或“新对象”创建)。 洛达斯州
检查给定值是否是由对象构造函数创建的对象。 我知道宿主对象与使用“{}”或“new Object”构造的对象不同,所以我想我的问题是:宿主对象应该算作普通对象吗 目前,实用程序是一致的,并且表示它们不是一致的,其他例程对不同浏览器上的主机对象给出不同的结果 编辑:结果的准确性对我来说是最重要的因素,性能是次要考虑因素 3个库的性能结果和建议的备选方案可在 编辑:这是实用程序库函数,因此无需搜索代码
defineProperty(utility, "isPlainObject", {
value: (function () {
var o = {};
return function (obj) {
try {
return utility.isObject(obj) && getPrototypeOf(obj).isPrototypeOf(o);
} catch (e) {
return false;
}
};
}())
});
当在FireFox v19.0和Opera v12.14上执行时,上述三项都通过了测试
不,至少在Opera中,小提琴中的测试在以下方面失败:屏幕
,数学
,JSON
,DoError
,LSParserFilter
,DomImplementals
,window.Opera
,SVGEException
,以及文档实现
这是铬/铬中的一个bug吗
什么?不同的函数返回不同的结果?没有
对于四个对象中的每一个,正确的结果应该是什么(这样我就可以确定哪个函数最准确)
你如何定义“正确”?如何定义“普通对象”
我相信所有3个程序都使用以下标准:
检查对象是否为普通对象(使用“{}”或“新对象”创建) 这几乎不是一个有用的标准,因为您遇到差异的对象不是“创建的”——它们是碰巧存在的宿主对象(甚至是本机对象) 然而,我们可以比较这些函数使用的标准:
- jQuery非常奇怪;你可以读它的名字。简而言之:一个对象或函数,其[[Class]]不是
中的一个,没有truthy布尔数字符串函数数组日期RegExp Error
属性,没有指向自身的节点名
属性,并且没有窗口
属性,或者构造函数
的构造函数
属性拥有自己的原型
属性 它们似乎是为了跨浏览器支持而这样做的,但正如您所看到的,它在某些情况下会失败,因为您希望它不是一个普通对象isPrototypeOf
- 实用程序有点模糊,但检查本身很简单:一个对象,其[[Class]]是
,其原型是对象
(或者更确切地说,其原型有一个对象。原型
方法,为isPrototypeOf
生成{}
)true
- Lodash有一些像jQuery这样的奇怪之处,但没有那么难-您可以阅读。它首先检查对象类型且不为null,然后通过
从getPrototypeOf(getPrototypeOf(…)
方法(如果存在)获取valueOf
。如果找到一个,则对象或其原型必须是object.prototype
对象,并且它不能是对象。prototype
对象。如果它没有找到一个,它会回到我不打算在这里解释的问题 所有这些都是为了支持使用不同的参数
对象和不提供对象、prototype
方法的浏览器检测来自不同环境(例如iFrame)的普通对象getPrototypeOf
- “备选方案”实现:这将测试对象的原型是否为
(但明确排除null
)或是否为object.prototype
,以及[[Class]]值是否为object.prototype
对象
- 就像它是由新对象创建的一样
然后只要
就可以了(如果您不需要支持跨帧对象的话)。getPrototypeOf(obj)==Object.prototype
和Math
对象将满足此要求JSON
- 在原型上没有干扰的可枚举属性
然后您还可以允许
,甚至可以像lodash那样手动检查可枚举属性。例如,这将包括getPrototypeOf(obj)==null
作为“普通对象”Object.prototype
- 可由
然后还添加检查[[Class]]是否为新对象创建
,以排除本机对象,如Object
、JSON
、Math
,以及所有具有特定于实现的类的主机对象。你真的愿意吗参数