我最近偶然发现了这个函数,它可以确定某个对象是否是JavaScript的普通对象:
function isPlainObject (value){
if (typeof value !== 'object' || value === null) return false;
let proto = value;
while (Object.getPrototypeOf(proto) !== null) {
proto = Object.getPrototypeOf(proto);
}
return Object.getPrototypeOf(value) === proto;
};
来源:https://github.com/redux-utilities/redux-actions/blob/master/src/utils/isPlainObject.js
我想知道:
1.如果下面的方法将做完全相同的东西?
1.如果是这样的话,是否可以认为是更有效呢?
function isPlainObj(value){
if (typeof value !== 'object' || value === null) return false;
let obj = {};
return Object.getPrototypeOf(value) === Object.getPrototypeOf(obj)
}
4条答案
按热度按时间x9ybnkn61#
检查一个值是否是普通对象:
排除空值、标量、数组、函数和除Object以外的任何扩展类型。
63lcw9qa2#
1.前者遍历整个原型链,但仅当该链由1个原型组成时才返回true(因此,您的第一个示例有点无意义)
1.是也不是。是的,它更有效,不需要循环所有东西只是为了检查原型是
Object.prototype
。不,它执行不必要的操作。我会这么做
如果您只想知道
value
原型是Object.prototype
,则无需太过复杂。👋**P.S.**有一件事 * 你的初始示例做了其他示例,包括我的,没有:它与外来对象一起工作,外来对象是来自不同领域的对象(即,iframes)。我不认为这个用例在2021年存在,但如果你的应用/网站在不同的窗口/框架之间传递对象 *,那么 * 第一个函数也会为这些对象返回
true
,而我的建议,或者你的建议,不会。然而,没有必要循环整个链,你可以简单地这样做:这会抓取proto一次或最多两次,确保其链以
null
结束,这通常是常见的文字情况。然而,我认为这些天外来物体是不存在的,所以我坚持我的建议版本。
v1uwarro3#
无论是OP问题中提供的方法,还是@Javier Rey的答案,在某些情况下,这两种方法都不能很好地工作。Atomics、具有
Symbol.iterator
或Symbol.toStringTag
静态数据属性的对象和JSON
namespace object以下测试用例将失败:
所以我们需要对这些物体进行额外的检查。
3qpi33ja4#
ToolJS在它的“Obj”模块下有一个方法,用于检查对象是否实际上是普通对象文字。
参考:ToolJS Object Module
在NPM上或通过其CDN获取代码,并按如下所示使用
您可以查看它的完整文档here
在后台,该方法检查项目类型不是null或undefined而是一个对象,然后检查其构造函数以查看其是否是一个对象,之后它确保它不是数组,最后将其转换为字符串以查看其是否是普通对象。