如果主机对象算作一个isPlainObject功能简单的对象吗?(Should host objec

2019-08-17 10:26发布

我一直在做从不同的浏览器不同的库的isPlainObject功能一些测试。

有上宽范围的对象的被测试4种不同的(代码明智)isPlainObject功能:

  • jQuery的
  • lodash
  • 工具(即我工作的一个库)
  • 替代方案,建议在下面的评论

对铬v23.0.1271.95上面显示差异这四个通过Chrome浏览器v25.0.1364.160,火狐v 19.0的歌剧v12.14,但效用至少给假为这些对象上所有的浏览器相同的反应

上的jsfiddle测试时,在Chrome上运行

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
  • 真正成为了日常认为对象是平原,而假是不是纯

编辑:我相信所有的程序都使用类似如下标准

jQuery的状态
检查以查看是否一个对象是一个普通的对象(使用创建“{}”或“新对象”)。

lodash状态
检查是否一个给定的值是由对象构造创建的对象。

据我所知,主机对象是不一样的,通过使用构造的对象“{}”或“新对象”,所以我想我的问题是:应该主机对象算作普通的对象?

目前,效用是洽,并说他们没有,其他的程序得到不同的结果在不同的浏览器的主机对象。

编辑:结果的准确性是最重要的因素对我来说,性能是次要的考虑因素。

3个库和建议的替代的性能结果可在jsperf

编辑:这是实用程序库功能,所以你不需要通过代码进行搜索。

defineProperty(utility, "isPlainObject", {
    value: (function () {
        var o = {};

        return function (obj) {
            try {
                return utility.isObject(obj) && getPrototypeOf(obj).isPrototypeOf(o);
            } catch (e) {
                return false;
            }
        };
    }())
});

Answer 1:

所有这三个以上的时上的FireFox v 19.0一个Opera v12.14执行通过测试

不,至少在Opera的小提琴测试失败window.screenMathJSONDOMErrorLSParserFilterDOMImplementationLSwindow.operaSVGExceptiondocument.implementation

这是在Chrome /铬的错误吗?

什么? 不同的函数返回不同的结果? 没有。

并为每个四个对象,都应该正确的结果是什么(所以我可以决定哪些功能是最准确的)?

你如何定义“正确”? 你如何定义“普通对象”?

我相信,所有3个例程使用下列标准:

检查以查看是否一个对象是一个普通的对象(使用创建“{}”或“新对象”)。

这是几乎没有一个有用的标准,因为那些遇到不一致的对象不是“创造” - 它们是主机对象(甚至是原生对象)恰好存在。

然而,我们可以比较这些功能使用的标准:

  • jQuery是很奇怪; 你可以阅读它在github上的源代码 。 简而言之:一个对象或功能,其[[类]]是没有一个Boolean Number String Function Array Date RegExp Error ,具有不是truthy nodeName属性,其具有不是一个window指向其自身属性,并且不具有constructor财产或者其prototype的财产constructor有一个自己的isPrototypeOf财产。

    他们似乎对跨浏览器支持这样做,但你可以看到它在某些情况下失败,你将有它预期不是一个普通的对象。

  • 效用是有点模糊,但检查本身是简单的:一个对象,其[[类]]是Object ,其原型为Object.prototype (或者更确切地说,它的原型具有isPrototypeOf其产生方法true{}

  • Lodash有一些古怪像jQuery,但并不难-你可以阅读在github上源 。 它对于对象类型和非空首先检查,然后得到Object.prototype经由getPrototypeOf(getPrototypeOf(…))从一个valueOf方法,如果它的存在。 如果它发现一个,无论是对象还是其原型一定是Object.prototype的对象,它不能是Arguments对象。 如果它没有找到一个,它回落到垫片这我不打算在这里解释。

    所有这些事情完成,以支持从不同的环境检测纯对象(例如I帧)与不同Object.prototype对象并在浏览器中,不提供一个getPrototypeOf方法。

  • 选择 ”执行:这测试对象的原型为任一null (但不包括显式Object.prototype )或为Object.prototype和[[类]]值为Object

应主持人的对象算作普通的对象?

也许。 它总是取决于你的使用情况?

  • 喜欢它的行为是由创建new Object

    然后,只需getPrototypeOf(obj) == Object.prototype应罚款(如果你不需要支持跨框架对象)。 在MathJSON对象将满足这一要求。

  • 对原型无干扰枚举的属性

    然后,你还可以允许getPrototypeOf(obj) == null甚至手动检查枚举的属性,如lodash一样。 现在,这将包括Object.prototype作为一个“普通对象”为例。

  • 可创建的new Object

    然后还加了检查[[类]为Object ,以排除像本地对象JSONMathArguments和所有主机对象与具体实现类。 你真的希望那些在测试函数传递isPlainObject ,他们会造成破坏,如果他们通过了其他检查?

另见你说什么? 在niftysnippets.org (由TJCrowder博客)



文章来源: Should host objects be counted as plain objects in an isPlainObject function?