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的类型系统确实有点乱,但我们没必要追求完美的判断方式。只要在你的业务场景下能正确工作,就是好方法

相关推荐
ccc10183 分钟前
通过学长的分享,我学到了
前端
编辑胜编程3 分钟前
记录MCP开发表单
前端
可爱生存报告4 分钟前
vue3 vite quill-image-resize-module打包报错 Cannot set properties of undefined
前端·vite
__lll_4 分钟前
前端性能优化:Vue + Vite 全链路性能提升与打包体积压缩指南
前端·性能优化
weJee4 分钟前
pnpm原理
前端·前端工程化
小高0076 分钟前
⚡️ Vue 3.5 正式发布:10× 响应式性能、SSR 水合黑科技、告别 .value!
前端·javascript·vue.js
乡村中医6 分钟前
🔥如何在函数式编程中使用设计模式-单例模式
前端·代码规范
葡萄城技术团队9 分钟前
【前沿解析】JavaScript 的未来,将迎来哪些新特性?
javascript
撰卢42 分钟前
总结一下vue3的组件之间数据转递,子组件传父组件,父组件传子组件
前端·javascript·vue.js
前端开发爱好者1 小时前
Vue3 超强“积木”组件!5 分钟搞定可交互 3D 机房蓝图!
前端·javascript·vue.js