js判断对象(object)、数组(Array)是否为空

本文探讨了在JavaScript中判断对象是否为空的多种方法,包括直接判断、序列化比较及使用ES6的Object.keys()方法,并提供了实际代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天又遇到了需要判断对象是否为空的需求,想着与其每次都去网上找,不如自己做个笔记。

js一个很方便的特点就是判断为True的写法是十分灵活的。比如,当我们判断一串文本是否为空时可以直接对这个变量进行判断。

let str = "我不是空的";
if(str)
	console.log(1);
else
	console.log(0);
// 1

类似的还可以用来判断数字是否不等于0,是否不等于null,是否不等于undefined。但是对于数组或者对象却不能直接这么判断。如果是数组的话要判断是否为空,推荐使用

let array = [];
if(array.length>0)
	console.log(1);
else
	console.log(0);
// 0 

至于object对象就比较麻烦了点。 根据自己的经验总结了几种方式,用于不同的用途。

1. 判断某个具体属性是否存在

if(object.id)
  Console.log(1)
  //存在ID这个属性时执行

这种方法的使用范围是最小的,使用起来时最简单的。但它需要明确知道这个对象是否会有某个属性才适用。

2. 序列化时判断是否 == “{}”

let object = {}, objectStr = "";
objectStr = JSON.stringify(object);
 if (objectStr != "{}")
	let stringify= JSON.stringify(changerData);

这种是利用的序列化会传回一串Json文本的特性来进行检查的。

3. 利用ES6的Object.keys()

这个得在支持ES6规则的时候才适用。

Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for…in 循环遍历该对象时返回的顺序一致 。如果对象的键-值都不可枚举,那么将返回由键组成的数组。
MDN 关于 Object.keys()的解释

var data = {};
var arr = Object.keys(data);
if(arr.length > 0)
	console.log(1);
else
	console.log(0);
// 0 

参考文档 mhbsoft的博客

<think>我们有一个问题:如何判断数组对象是否?参考了多个引用,我们可以总结如下: 1. 对于数组: - 使用 `Array.isArray()` 判断是否数组。 - 使用 `length` 属性判断长度是否为0。 2. 对于对象: - 使用 `typeof` 判断是否对象(注意排除null,因为typeof null也是'object')。 - 使用 `Object.keys(obj).length === 0` 来判断对象是否没有自身可枚举属性。 - 注意:对象可能不是普通对象(比如是Date、Array等),所以我们可以先判断它是普通对象(即`constructor === Object`)?但根据需求,我们通常只关心它是否有键值对,所以即使是非普通对象(如自定义类实例),只要没有可枚举属性,也可以认为是。 3. 另外,引用[5]提供了一个综合函数,可以判断任意值是否(包括null, undefined, 字符串,数组对象)。 根据用户的问题,他想要判断数组对象是否。注意:这里“数组对象”可能是指数组或者对象。我们可以分别处理。 但是注意:数组对象在JavaScript中都是“真值”(truthy),所以不能直接用if判断,需要分别处理。 我们参考引用[5]中的函数,并考虑引用[1][2][3][4]中的方法,可以这样实现: 步骤: 1. 判断是否为null或undefined:直接返回true(表示)。 2. 判断是否为字符串:字符串则返回true。 3. 判断是否数组:使用Array.isArray(),然后判断length是否为0。 4. 判断是否对象:使用typeof,并且要排除null(因为typeof null是'object',但第一步已经排除了null,所以这里可以安全使用)。然后判断对象的键的个数是否为0。 注意:函数可能会遇到一些边界情况,比如函数、日期、正则表达式等,它们也是对象,但通常我们不会认为它们是的,因为它们有内部属性(但通常不可枚举)。所以,我们只考虑可枚举属性。 因此,我们可以这样写: ```javascript function isEmpty(value) { // 处理 null 和 undefined if (value == null) { return true; } // 处理字符串:字符串 if (typeof value === 'string') { return value.trim() === ''; } // 处理数组 if (Array.isArray(value)) { return value.length === 0; } // 处理对象:普通对象或类对象(注意:数组已经在上一步处理过了) if (typeof value === 'object') { // 使用Object.keys()获取可枚举的自身属性 return Object.keys(value).length === 0; } // 其他类型(如数字、布尔值、函数等)默认不为 return false; } ``` 测试用例: ```javascript console.log(isEmpty(null)); // true console.log(isEmpty(undefined)); // true console.log(isEmpty('')); // true console.log(isEmpty(' ')); // true(注意:这里我们用了trim,所以格字符串也会被认为是) console.log(isEmpty([])); // true console.log(isEmpty({})); // true console.log(isEmpty([1,2,3])); // false console.log(isEmpty({a:1})); // false console.log(isEmpty(0)); // false(数字0不为) console.log(isEmpty(false)); // false console.log(isEmpty(function(){})); // false(函数不为) console.log(isEmpty(new Date())); // false(日期对象,通常有可枚举属性吗?实际上,Object.keys(new Date()).length为0,所以返回true?但注意:日期对象我们通常不认为是对象,但按照我们的函数逻辑,它会被视为,因为它的可枚举自身属性确实为。所以这里需要根据需求调整。) ``` 关于日期对象:日期对象本身没有可枚举的自身属性,所以会被判断。但这是否符合预期?这取决于你的使用场景。如果你希望日期对象不为,那么你可能需要调整逻辑,比如不把日期对象当作普通对象判断,而是直接返回false。 因此,我们可以改进:在判断对象之前,先排除一些特殊的对象(如Date、RegExp等)。我们可以通过检查对象的构造函数来判断。 改进版本: ```javascript function isEmpty(value) { if (value == null) return true; if (typeof value === 'string') return value.trim() === ''; if (Array.isArray(value)) return value.length === 0; // 如果是对象类型(且不是数组,因为数组已经处理过) if (typeof value === 'object') { // 检查是否是一些内置的非纯对象(这些对象即使没有可枚举属性,也不应算) if (value instanceof Date || value instanceof RegExp || value instanceof Map || value instanceof Set) { return false; // 这些对象我们视为非,因为即使没有内容,它们也有自己的用途,且通常不按键值对判断 } // 普通对象或类对象 return Object.keys(value).length === 0; } return false; } ``` 测试: ```javascript console.log(isEmpty(new Date())); // false,因为我们在判断对象时,遇到Date对象直接返回false(即非) console.log(isEmpty(new RegExp())); // false console.log(isEmpty(new Map())); // false(虽然Map是的,但我们不希望认为它是,因为它是特殊对象) console.log(isEmpty(new Set())); // false ``` 但是,如果用户传入一个的Map或Set,我们是否应该认为它是的?这取决于需求。上面的函数对于Map和Set返回false(非),即使它们没有元素。如果我们希望判断Map和Set是否,我们可以单独处理: 更全面的版本: ```javascript function isEmpty(value) { if (value == null) return true; if (typeof value === 'string') return value.trim() === ''; if (Array.isArray(value)) return value.length === 0; if (value instanceof Map || value instanceof Set) return value.size === 0; if (typeof value === 'object') { // 如果是Date、RegExp等,我们视为非?但有时我们可能想判断其内容,但这里我们只考虑普通对象 // 或者我们可以排除这些特殊对象,即它们不为,或者我们也可以认为它们没有可枚举属性就是?但这样可能不合适。 // 根据引用[5]的示例,它只处理普通对象。所以这里我们只处理普通对象(即键值对集合),而其他对象(如Date)我们返回false(非)?或者我们可以让用户知道这个函数不适用于这些类型? // 另一种思路:如果对象有自定义的isEmpty方法,就调用它?但这里我们不展开。 // 我们这里只处理普通对象(纯对象)和类对象(没有特殊内置对象特征),但如何判断对象? // 我们可以通过构造函数来判断Object.prototype.toString.call(value) === '[object Object]' if (Object.prototype.toString.call(value) === '[object Object]') { return Object.keys(value).length === 0; } // 其他对象(如Date、RegExp等)我们视为非,因为无法用对象的概念去衡量 return false; } return false; } ``` 这样,普通对象({})会返回true,而Date、RegExp等对象返回false(非)。同时,我们也可以处理Map和Set。 但是,如果用户传入一个自定义类的实例,并且这个实例没有可枚举属性,那么它会被判断为非(因为它的`Object.prototype.toString.call(value)`可能是`[object Object]`吗?不一定,如果自定义类没有覆盖toStringTag,那么可能是`[object Object]`,但通常自定义实例的`Object.prototype.toString.call`返回的是`[object Object]`?实际上,自定义类的实例的`[[Class]]`内部属性是`Object`,所以会返回`[object Object]`。因此,自定义类的实例如果没有可枚举属性,也会被判断。 但是,自定义类可能有自己的属性,但可能是不可枚举的。所以,我们只考虑可枚举属性。 因此,我们可以这样写: ```javascript function isEmpty(value) { // 处理 null 和 undefined if (value == null) { return true; } // 处理字符串 if (typeof value === 'string') { return value.trim() === ''; } // 处理数组 if (Array.isArray(value)) { return value.length === 0; } // 处理Set和Map if (value instanceof Set || value instanceof Map) { return value.size === 0; } // 处理对象 if (typeof value === 'object') { // 如果是普通对象(通过原型判断) if (value.constructor === Object) { return Object.keys(value).length === 0; } // 如果是其他类型的对象(包括自定义对象、内置对象等),我们检查其是否有可枚举属性 // 注意:有些对象可能没有可枚举属性,但我们认为它们不为?或者我们也可以检查所有自身属性(包括不可枚举)?但通常我们用Object.keys就够了(只包括可枚举自身属性) // 但是,对于非普通对象,我们可能不想判断,比如一个没有可枚举属性的对象,但它是某个类的实例,可能内部有状态。所以这里我们统一:对于非普通对象,如果它没有可枚举的自身属性,就认为为?这取决于需求。 // 另一种做法:对于非普通对象,我们直接返回false(认为非),因为无法判断。 // 这里我们采用:如果对象是普通对象,则按属性数量判断;否则,我们使用Object.keys()判断可枚举属性数量,如果为0则返回true,否则false?但这样可能会把没有可枚举属性的非普通对象判断。 // 为了安全起见,我们只对普通对象进行判断,其他对象一律返回false(非)?但这样可能不够全面。 // 根据需求,我们可能希望判断一个对象是否(没有可枚举属性),不管它是什么类型。所以我们可以统一使用Object.keys(),但这样可能会把一些不应该为对象(如Date)判断。所以我们需要排除一些内置对象吗? // 我们这里采用:如果对象是内置对象(如Date, RegExp, Function等),我们返回false(非)。否则,我们检查它的可枚举属性数量。 // 但是如何判断内置对象?我们可以通过判断它的构造函数是否是内置的。 const builtInTypes = [Date, RegExp, Function]; // 可以继续扩展 if (builtInTypes.some(type => value instanceof type)) { return false; } // 其他对象,包括普通对象和自定义对象,都通过可枚举属性数量判断 return Object.keys(value).length === 0; } // 其他类型(数字、布尔值、函数等)不为 return false; } ``` 这个函数比较复杂,而且可能无法覆盖所有情况。根据引用[5]中的示例,它只处理普通对象,所以我们也可以简化:只处理普通对象(即字面量对象{}),对于其他对象类型(如Date、自定义类实例等)我们不判断,直接返回false(非)?或者我们也可以认为这些对象永远不为?这取决于需求。 考虑到简单性和大多数情况,我们可以采用引用[5]中的方法,只处理普通对象(即通过`{}`或`new Object`创建的对象)和数组、字符串等。对于其他对象,我们返回false(即非)。这样,如果用户传入一个的自定义对象,我们不会认为它是的,因为它的构造器不是Object。但这样可能不符合用户预期。 因此,我们可以提供两个版本: 版本1(简单版,只处理普通对象): ```javascript function isEmpty(value) { if (value == null || value === '') return true; if (Array.isArray(value)) return value.length === 0; if (typeof value === 'object' && value.constructor === Object) { return Object.keys(value).length === 0; } return false; } ``` 版本2(处理更多类型,包括Map, Set和字符串格,以及普通对象): ```javascript function isEmpty(value) { if (value == null) return true; if (typeof value === 'string') return value.trim() === ''; if (Array.isArray(value)) return value.length === 0; if (value instanceof Map || value instanceof Set) return value.size === 0; if (typeof value === 'object') { // 如果是普通对象 if (value.constructor === Object) { return Object.keys(value).length === 0; } // 其他对象,我们检查是否有可枚举属性(包括自定义对象) return Object.keys(value).length === 0; } return false; } ``` 版本2中,对于非普通对象(自定义对象),我们仍然检查其可枚举属性。这样,如果一个自定义对象没有可枚举属性,它也会被认为是的。 但注意:有些对象可能没有可枚举属性,但有不可枚举属性,这种情况我们仍然认为它为(因为我们只关心可枚举属性)。这通常是合理的。 根据用户问题,他可能只需要判断数组对象(普通对象)。所以我们可以采用简单版本,只处理数组和普通对象,以及null, undefined, 字符串。 因此,最终代码(根据用户需求,只处理数组和普通对象): ```javascript function isEmpty(value) { // 检查 null 和 undefined if (value == null) { return true; } // 检查数组 if (Array.isArray(value)) { return value.length === 0; } // 检查普通对象 if (value.constructor === Object) { return Object.keys(value).length === 0; } // 其他类型,我们返回false(非)?或者也可以考虑字符串,但用户只问数组对象 // 但是用户问题中提到了“数组对象”,所以我们只处理数组对象,其他类型不处理,返回false(非)?或者我们可以抛出错误?但通常我们返回false表示非。 return false; } ``` 但是,这个函数对于字符串、Map等会返回false,因为用户只关心数组对象。如果用户还想判断字符串,那么需要扩展。 根据用户问题:“我想判断数组对象是否”,这里的“数组对象”可能是指数组或者对象。所以我们只处理数组和普通对象。 测试: ```javascript isEmpty([]) // true isEmpty({}) // true isEmpty([1,2]) // false isEmpty({a:1}) // false isEmpty(null) // true isEmpty(undefined) // true isEmpty("") // false (因为不是数组对象,所以返回false,但用户可能希望字符串也是,所以这里需要明确) ``` 所以,如果用户希望同时判断字符串,那么需要修改函数。根据引用[5]中的示例,用户可能希望判断多种类型的值。因此,我们提供更通用的版本,但明确说明。 我们采用引用[5]中的函数,并稍作调整(不处理Map和Set,但处理字符串): ```javascript function isEmpty(value) { // 判断 null, undefined 或字符串 if (value == null || value === '') { return true; } // 判断数组 if (Array.isArray(value)) { return value.length === 0; } // 判断对象(普通对象) if (typeof value === 'object') { // 注意:这里typeof null也是'object',但第一步已经排除了null return Object.keys(value).length === 0; } // 其他类型(数字、布尔值、函数等)默认不为 return false; } ``` 这个函数可以处理: - null, undefined: true - 字符串: true - 数组: true - 普通对象: true - 非数组/对象: false - 非字符串: false - 数字0: false - 布尔值false: false 注意:字符串(包括格字符串)不会被处理为true,因为这里我们只检查严格等于字符串。如果希望格字符串也被视为,可以用`value.trim() === ''`,但注意:如果value是字符串,那么trim()是安全的,如果是其他类型,则不能调用trim。所以: ```javascript function isEmpty(value) { if (value == null) return true; if (typeof value === 'string') return value.trim() === ''; if (Array.isArray(value)) return value.length === 0; if (typeof value === 'object') { return Object.keys(value).length === 0; } return false; } ``` 这样,对于格字符串,我们会返回true。 总结:我们推荐使用这个通用函数来判断一个值是否(包括null, undefined, 字符串(包括格)、数组对象(普通对象))。 但是,对于非普通对象(如Date、自定义类实例),我们也会判断其可枚举属性,如果没有可枚举属性,则返回true(即认为)。这可能会带来一些意外,比如一个Date对象,它没有可枚举属性,那么会被认为。但根据引用[4],我们可以先判断对象类型,只对普通对象进行判断。所以,为了避免这个问题,我们可以修改为: ```javascript function isEmpty(value) { if (value == null) return true; if (typeof value === 'string') return value.trim() === ''; if (Array.isArray(value)) return value.length === 0; if (typeof value === 'object') { // 如果是普通对象(通过构造函数判断) if (value.constructor === Object) { return Object.keys(value).length === 0; } else { // 非普通对象,我们不认为它是的,或者也可以根据需求返回false(非) return false; } } return false; } ``` 这样,非普通对象(如new Date())就会返回false,即使它没有可枚举属性。 根据用户需求,如果用户只关心数组和普通对象,那么这样写是合理的。 因此,最终我们提供以下函数: ```javascript /** * 判断是否 * @param {any} value - 需要判断的值 * @returns {boolean} - 如果值为(null, undefined, 字符串(包含格)、数组普通对象),返回true;否则返回false。 */ function isEmpty(value) { if (value == null) return true; if (typeof value === 'string') return value.trim() === ''; if (Array.isArray(value)) return value.length === 0; if (typeof value === 'object' && value.constructor === Object) { return Object.keys(value).length === 0; } return false; } ``` 测试: ```javascript console.log(isEmpty(null)); // true console.log(isEmpty(undefined)); // true console.log(isEmpty('')); // true console.log(isEmpty(' ')); // true console.log(isEmpty([])); // true console.log(isEmpty({})); // true console.log(isEmpty([1,2])); // false console.log(isEmpty({a:1})); // false console.log(isEmpty(0)); // false console.log(isEmpty(false)); // false console.log(isEmpty(new Date())); // false(非普通对象) console.log(isEmpty(/regex/)); // false(非普通对象) console.log(isEmpty(function(){})); // false(函数,typeof不是'object',所以会走最后的false) ``` 这个函数可以满足大部分需求,并且避免了对非普通对象的错误判断。 如果用户需要判断Set、Map等,可以自行扩展。 回答用户问题:在JavaScript中,判断数组对象是否的方法如上所述,可以使用上述函数,也可以根据具体类型单独判断: - 数组:`Array.isArray(arr) && arr.length === 0` - 普通对象:`obj.constructor === Object && Object.keys(obj).length === 0` 注意:单独判断时,普通对象需要同时满足构造器是Object且属性数量为0,以避免将非普通对象误判。</think>在 JavaScript 中,判断数组对象是否需要根据数据类型采用不同的方法。以下是详细的判断方法和代码示例: ### 一、判断数组是否 ```javascript const arr = []; // 方法1:检查length属性(推荐) if (arr.length === 0) { console.log("数组"); } // 方法2:使用Array.isArray()确保是数组 if (Array.isArray(arr) && arr.length === 0) { console.log("数组"); } // 方法3:JSON序列化(不推荐,效率低) if (JSON.stringify(arr) === "[]") { console.log("数组"); } ``` ### 二、判断对象是否 ```javascript const obj = {}; // 方法1:检查Object.keys()长度(推荐) if (Object.keys(obj).length === 0) { console.log("对象"); } // 方法2:结合constructor类型检查 if (Object.keys(obj).length === 0 && obj.constructor === Object) { console.log("对象"); } // 方法3:JSON序列化(不推荐,效率低) if (JSON.stringify(obj) === "{}") { console.log("对象"); } ``` ### 三、通用判断函数(处理多种类型) ```javascript function isEmpty(value) { // 处理 null 和 undefined if (value == null) return true; // 处理字符串 if (typeof value === "string") return value.trim() === ""; // 处理数组 if (Array.isArray(value)) return value.length === 0; // 处理对象 if (typeof value === "object") { // 检查特殊对象类型 if (value instanceof Date || value instanceof RegExp) return false; return Object.keys(value).length === 0; } return false; } // 测试用例 console.log(isEmpty(null)); // true console.log(isEmpty(undefined)); // true console.log(isEmpty("")); // true console.log(isEmpty(" ")); // true(格字符串) console.log(isEmpty([])); // true console.log(isEmpty({})); // true console.log(isEmpty([1, 2])); // false console.log(isEmpty({ a: 1 })); // false console.log(isEmpty(new Date())); // false(日期对象不为) ``` ### 关键注意事项: 1. **数组判断**: - 数组 `[]` 的 `length` 属性为 0 - 使用 `Array.isArray()` 确保目标确实是数组[^2][^3] 2. **对象判断**: - 对象 `{}` 的 `Object.keys()` 返回数组 - 需检查 `constructor === Object` 避免将特殊对象(如 Date)误判为[^1][^4] - `JSON.stringify()` 效率较低,不推荐用于大型对象 3. **特殊类型处理**: - `null` 和 `undefined` 直接视为 - 字符串需用 `trim()` 处理格 - 内置对象(如 Date、RegExp)即使没有属性也不应视为[^5] 4. **边界情况**: ```javascript console.log(isEmpty(new Map())); // 返回false(需单独处理) console.log(isEmpty(new Set())); // 返回false(需单独处理) ``` > 推荐使用 `Object.keys().length` 判断对象,用 `arr.length` 判断数组,并在通用函数中加入类型保护逻辑[^1][^3][^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值