JavaScript中如何判断一个对象是否为普通(plain)对象?
JavaScript判断普通键值对象的可靠方法
直接给出可落地的实现代码:
function isPlainObject(val) { // 过滤非对象、null的情况 if (typeof val !== 'object' || val === null) return false // 过滤数组、错误、Date等内置特殊对象 if (Object.prototype.toString.call(val) !== '[object Object]') return false // 校验原型链,排除自定义类实例 const proto = Object.getPrototypeOf(val) // 兼容Object.create(null)创建的无原型纯对象 return proto === null || proto === Object.prototype }
测试验证效果:
- 普通键值对象
{"a":3}→ 返回true - 数组
[1,2,3]→ 返回false - 自定义类实例
new Foo()→ 返回false - 错误实例
new Error()→ 返回false - 日期对象
new Date()→ 返回false - 无原型对象
Object.create(null)→ 返回true
方法逻辑说明:
- 第一步过滤是为了避开
typeof null === 'object'的历史遗留问题,同时把所有非对象类型直接排除 - 第二步用
Object.prototype.toString.call读取对象的内部类型标记,这个方法不会被自定义的toString方法覆盖,能准确识别所有内置特殊对象类型,一次性排除所有非纯对象标记的内置对象 - 第三步通过原型判断排除自定义类的实例:所有通过
class或者构造函数自定义的类,它的实例原型指向的是类的prototype属性,而非Object.prototype,直接对比就能区分。另外Object.create(null)创建的没有原型的纯键值对象,通常业务里也会归为普通对象,所以单独做了兼容。
如果你的项目里已经引入了Lodash,也可以直接调用现成的_.isPlainObject()方法,底层逻辑和上面的实现一致。
内容的提问来源于stack exchange,提问作者Julian Lachniet
相关产品推荐
相关产品推荐

