阅读 2886

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

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

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

判断变量是不是对象

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

复制代码

null

typeof 即可做一个简单的判断,但是要注意 null 因为typeof null === 'object' 为 true

所以判断是不是对象的语句如下

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

[]

因为 typeof [] === 'object'

Array.isArray(obj) 判断

所以判断是不是对象的终极语句如下

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

效果如下

Object.prototype.toString.call

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

so

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

判断对象是不是空对象

经过上面对象的判断之后,确定是对象的前提下,怎么确定这个对象是一个空对象呢?

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)
}


复制代码

文章分类
前端
文章标签