对象{}
,它明明看着是空的,但JS说它"不是假值",if ({})
还是成立的。这就尴尬了。
到底怎么才算"空对象"?又怎么知道一个东西到底是对象、数组、还是别的啥?
一、怎么判断一个对象是否为空?
先说结论:一个"空对象"通常是指它没有任何可枚举的自有属性。
比如:
js
const obj1 = {};
const obj2 = { name: '张三' };
obj1
是空的,obj2
不是。
方法1:Object.keys()
这是我现在最常用的方法。
js
function isEmpty(obj) {
return Object.keys(obj).length === 0;
}
isEmpty({}); // true
isEmpty({ name: '张三' }); // false
使用场景:我之前做后台管理系统,有个接口返回用户配置:
js
const config = await fetchConfig();
if (isEmpty(config)) {
alert('请先设置你的偏好');
}
这个方法简单直接,而且只看对象自己的属性,不看原型链,很安全。
注意:它只适用于普通对象。比如数组、函数这些,也可以用
Object.keys()
。但数组更自然的判断是arr.length === 0
。
方法2:for...in
遍历
老派但可靠的方法:
js
function isEmpty(obj) {
for (let key in obj) {
return false; // 只要能进循环,说明有属性
}
return true;
}
这个方法也行,但要小心原型链上的属性。比如:
js
const obj = {};
obj.__proto__.abc = 'xxx'; // 别这么干,只是举例
这时候for...in
会遍历到abc
,但Object.keys()
不会。
所以如果你不确定对象有没有被"污染"原型,建议配合 hasOwnProperty
:
js
function isEmpty(obj) {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
return false;
}
}
return true;
}
不过现在大家一般不乱改原型了,所以 Object.keys
更省心。
方法3:JSON.stringify()
有人这么写:
js
JSON.stringify(obj) === '{}'
这方法能用,但有坑:
- 如果对象里有
undefined
、函数、Symbol,会被忽略,结果可能不准。 - 性能差一点,毕竟要序列化。
所以我不推荐,除非你特别确定数据结构。
二、怎么区分数据类型?
JS的类型判断一直是个"玄学"。比如:
js
typeof [] // "object"
typeof null // "object"
这就很离谱。所以我们得用别的办法。
1. 判断是不是数组
别再用typeof
了,用Array.isArray()
:
js
Array.isArray([]) // true
Array.isArray({}) // false
使用场景:我之前写一个数据处理函数,接收的参数可能是单个对象,也可能是对象数组:
js
function handleData(data) {
const list = Array.isArray(data) ? data : [data];
list.forEach(item => console.log(item));
}
handleData({name: '张三'}); // 包装成数组
handleData([{name: '张三'}]); // 直接用
这样写,调用方就不用每次都包数组了,很灵活。
2. 判断是不是 null 或 undefined
这个简单:
js
if (value == null) { // 等价于 value === null || value === undefined
// 处理空值
}
用== null
比分开写两个条件更简洁,而且语义清晰。
3. 判断是不是普通对象(不是数组、不是 null、不是函数等)
有时候我们需要区分"纯对象"和别的类型。
可以用这个小技巧:
js
function isPlainObject(obj) {
return obj?.constructor === Object;
}
解释一下:
obj?.
是可选链,防止 obj 是 null/undefinedconstructor
属性指向构造函数- 普通对象的构造函数就是
Object
测试一下:
js
isPlainObject({}) // true
isPlainObject([]) // false,数组的 constructor 是 Array
isPlainObject(null) // false
isPlainObject(function(){}) // false,函数的 constructor 是 Function
这个方法在处理 API 返回数据时特别有用。比如:
js
// 假设接口可能返回对象或数组
const res = await api.getData();
if (isPlainObject(res)) {
showUserInfo(res);
} else if (Array.isArray(res)) {
showList(res);
}
小结
- 判断空对象 :优先用
Object.keys(obj).length === 0
- 判断数组 :用
Array.isArray()
- 判断 null/undefined :用
value == null
- 判断是不是普通对象 :用
obj?.constructor === Object
JS的类型系统确实有点乱,但我们没必要追求完美的判断方式。只要在你的业务场景下能正确工作,就是好方法。