判断对象是否为空
挑战介绍
本节我们来挑战一道大厂面试真题 —— 判断对象是否为空。
挑战准备
新建一个 isEmptyObject.js
文件,在文件里写一个名为 isEmptyObject
的函数,并导出这个函数,如下图所示:
这个文件在环境初始化时会自动生成,如果发现没有自动生成就按照上述图片自己创建文件和函数,函数代码如下:
function isEmptyObject(obj) {
// 补充代码
}
module.exports = isEmptyObject;
挑战内容
实现一个函数,判断传入的对象是否为空。如果对象为空返回 true,否则返回 false。
不必考虑传入原始类型的情况,本题测试用例中传入的参数都是对象类型。
示例:
输入:{}
输出:true
输入:{ name: 'lin' }
输出:false
注意事项
- 文件名、函数名不可随意更改。
- 文件中编写的函数需要导出,否则将无法提交通过。
题解
知识点
- for in
- Object.keys()
- JSON.stringify()
1.for in
首先可以用遍历解决,用的是 for in,思路如下:
- 遍历这个对象
- 如果能被遍历,说明这个对象有属性,返回
false
- 否则说明对象为空,返回
true
- 如果能被遍历,说明这个对象有属性,返回
代码实现如下:
function isEmptyObject(obj) {
for (let o in obj) {
return false;
}
return true;
}
2.Object.keys()
还有一种解题方式就是使用 Object.keys(),先把对象转化为数组,然后再根据数组的长度是否为零来判断对象是否为空。
代码实现如下:
function isEmptyObject(obj) {
return Object.keys(obj).length === 0;
}
虽然本题所有的测试用例都是引用类型,但是如果把本方法用到实际的项目中,传入的参数就是不可预知的了,很有可能就是一些奇怪的数据,比如传入 null
或 undefined
,就会出问题,如下代码所示:
function isEmptyObject(obj) {
return Object.keys(obj).length === 0;
}
isEmptyObject(null); // 会报错:无法将 null 转换为对象
isEmptyObject(undefined); // 会报错:无法将 未定义 转换为对象
所以在实际项目中,可以用如下方式实现本函数:
function isEmptyObject(obj) {
return Object.keys(obj || []).length === 0;
}
3.JSON.stringify()
还可以使用 JSON.stringify() 来解决本题,只需要判断对象转为 JSON
字符串之后,是不是等于 {}
即可,代码如下:
function isEmptyObject(obj) {
return JSON.stringify(obj) === "{}";
}
这么写判断大多数对象都不会有问题,不过一旦遇到出现“循环引用”的对象,就会报错,如下代码所示:
function isEmptyObject(obj) {
return JSON.stringify(obj) === "{}";
}
// 循环引用该对象。
const obj = {
a: 1,
};
obj.a = obj;
isEmptyObject(obj); // 报错
4.Object.getOwnPropertyNames()
可以用Object.getOwnPropertyNames方法获取对象的属性名,存到数组中,若长度为0,则为空对象
function isEmptyObject(obj) {
return Object.getOwnPropertyNames(obj).length==0;// 返回true
}
小结
- 判断对象为空,就使用
for in
或者Object.keys
来判断,尽量不要使用JSON.stringify
。 - 判断数组为空,一般判断长度为 0,也可以用和判断对象为空一样的方法来判断。
- 判断原始类型为空,就使用
!
运算符来判断。
前两种解答方式也是比较常见的,我用的第二种方法解题,直接先把对象转化为数组,然后判断数组的长度就可以了,要注意的地方就是True和False的返回条件要看清楚,不要弄反了。