JS里怎么判断一个对象是否为空?怎么分清它到底是啥类型?

对象{},它明明看着是空的,但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/undefined
  • constructor 属性指向构造函数
  • 普通对象的构造函数就是 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的类型系统确实有点乱,但我们没必要追求完美的判断方式。只要在你的业务场景下能正确工作,就是好方法

相关推荐
fruge21 分钟前
Vue Pinia 状态管理实战指南
前端·vue.js·ubuntu
sean1 小时前
开发一个自己的 claude code
前端·后端·ai编程
用户21411832636021 小时前
dify案例分享-用 Dify 一键生成教学动画 HTML!AI 助力,3 分钟搞定专业级课件
前端
chxii1 小时前
ISO 8601日期时间标准及其在JavaScript、SQLite与MySQL中的应用解析
开发语言·javascript·数据库
没逛够1 小时前
Vue 自适应高度表格
javascript·vue.js·elementui
太过平凡的小蚂蚁3 小时前
Kotlin 协程中常见的异步返回与控制方式(速览)
开发语言·前端·kotlin
咖啡の猫4 小时前
Vue初始化脚手架
前端·javascript·vue.js
晨枫阳4 小时前
uniapp兼容问题处理总结
前端·vue.js·uni-app
liusheng5 小时前
腾讯地图 SDK 接入到 uniapp 的多端解决方案
前端·uni-app
拉不动的猪5 小时前
如何处理管理系统中(Vue PC + uni-app 移动端):业务逻辑复用基本方案
前端·javascript·架构