判断一个变量是否是空对象 {}

判断一个变量是否是空对象有两步javascript

  1. 变量是否是对象
  2. 对象是否是空的

判断变量是否是对象

var obj;
// 初级版本
typeof obj === 'object'

复制代码

null

typeof 便可作一个简单的判断,可是要注意 null 由于typeof null === 'object' 为 truejava

因此判断是否是对象的语句以下数组

obj !== null && typeof obj === 'object'
复制代码

[]

由于 typeof [] === 'object'函数

Array.isArray(obj) 判断ui

因此判断是否是对象的终极语句以下spa

obj !== null && typeof obj === 'object' && !Array.isArray(obj)
复制代码

效果以下prototype

Object.prototype.toString.call

评论区大佬用一个比较简单的办法解决了判断是否是对象的问题3d

socode

Object.prototype.toString.call(obj) === '[object Object]'
复制代码

判断对象是否是空对象

通过上面对象的判断以后,肯定是对象的前提下,怎么肯定这个对象是一个空对象呢?cdn

Object.keys

它会先列举对象的全部可枚举属性键名到数组中,再判断数组的长度 Object.keys(obj).length === 0 对不可枚举的属性无效

JSON.stringify

JSON.stringify(obj) === {} 其没法转化函数键值对,同时对不可枚举的属性一筹莫展

Object.getOwnPropertyNames

Object.getOwnPropertyNames(obj).length === 0

能够获取到不可枚举的属性键,正解!!!

还要注意一种状况对象属性为 Symbol 的时候,Object.getOwnPropertyNames 没法检测出来,须要单独处理

当一个 symbol 类型的值在属性赋值语句中被用做标识符,该属性(像这个 symbol 同样)是匿名的;而且是不可枚举的。由于这个属性是不可枚举的,它不会在循环结构 “for( ... in ...)” 中做为成员出现,也由于这个属性是匿名的,它一样不会出如今 “Object.getOwnPropertyNames()” 的返回数组里。这个属性能够经过建立时的原始 symbol 值访问到,或者经过遍历 “Object.getOwnPropertySymbols()” 返回的数组。

因此要加上 Symbol 判断

Object.getOwnPropertySymbols(obj).length === 0
复制代码

Reflect.ownKeys

经评论区高人指点,发现 Reflect.ownKeys 既能够解决非枚举属性也能够解决Symbol属性。

总结

终极版判断一个变量是否是空对象的代码

obj !== null
&& typeof obj === 'object'
&& !Array.isArray(obj)
&& (Object.getOwnPropertyNames(obj).length === 0)
&& (Object.getOwnPropertySymbols(obj).length === 0)

// or
(Object.prototype.toString.call(obj) === '[object Object]')
&& (Object.getOwnPropertyNames(obj).length === 0)
&& (Object.getOwnPropertySymbols(obj).length === 0)

// or
(String(obj) === '[object Object]') && (Reflect.ownKeys(obj).length === 0)

复制代码

封装成函数以下

function isEmptyObj(obj) {
    return obj !== null
    && typeof obj === 'object'
    && !Array.isArray(obj)
    && (Object.getOwnPropertyNames(obj).length === 0)
    && (Object.getOwnPropertySymbols(obj).length === 0)
}
// or
function isEmptyObj(obj) {
    return (Object.prototype.toString.call(obj) === '[object Object]')
    && (Object.getOwnPropertyNames(obj).length === 0)
    && (Object.getOwnPropertySymbols(obj).length === 0)
}

// or
function isEmptyObj(obj) {
    return (String(obj) === '[object Object]') && (Reflect.ownKeys(obj).length === 0)
}


复制代码

相关文章
相关标签/搜索