推荐答案
// www.javascriptcn.com code example
function isEmptyObject(obj) {
if (obj == null) {
return true; // null 或 undefined 直接返回 true
}
if (typeof obj !== 'object') {
return false; // 非对象类型直接返回false
}
for (let key in obj) {
if (Object.hasOwn(obj, key)) {
return false; // 如果有自身属性,则不是空对象
}
}
return true; // 遍历完所有自身属性,都没有找到,则是空对象
}本题详细解读
概念理解
“空对象”指的是不包含任何自身属性的对象。原型链上的属性不应被考虑。
常见的错误方法与问题
Object.keys(obj).length === 0- 问题: 这种方法可以工作,但如果
obj是null或undefined,则会抛出错误。 - 改进: 需要首先处理
null和undefined的情况。 - 代码:
function isEmptyObject(obj) { if (obj == null) { return true; } return Object.keys(obj).length === 0; }- 问题: 这种方法可以工作,但如果
JSON.stringify(obj) === '{}'- 问题: 这种方法会忽略
Symbol属性和值为undefined的属性。并且性能较差。
- 问题: 这种方法会忽略
for...in循环不加hasOwnProperty判断- 问题:
for...in会遍历原型链上的属性,造成误判。
function isEmptyObject(obj){ for (let key in obj) { // 错误写法,没有使用 hasOwnProperty return false; } return true }- 问题:
推荐方法的原理与优势
if (obj == null) { return true; }- 作用: 快速处理
null和undefined,避免后续错误。 - 原因:
null和undefined都是假值,可以简单用==判等,这样可以同时处理null和undefined。
- 作用: 快速处理
if (typeof obj !== 'object') { return false; }- 作用: 确保传入参数是一个对象,如果传入的是其他的非对象类型,直接返回
false。
- 作用: 确保传入参数是一个对象,如果传入的是其他的非对象类型,直接返回
for (let key in obj) { if (Object.hasOwn(obj, key)) { return false; } }- 作用: 遍历
obj的所有自身属性(不包括原型链上的属性)。 Object.hasOwn(obj, key): 判断属性是否是自身属性。hasOwnProperty的替代方案,避免原型链污染,更加安全可靠。- 返回
false: 只要找到一个自身属性,就立即返回false,表示该对象非空。
- 作用: 遍历
return true;- 作用: 如果循环结束,说明没有找到任何自身属性,则对象为空,返回
true。
- 作用: 如果循环结束,说明没有找到任何自身属性,则对象为空,返回
总结
推荐的 isEmptyObject 函数能正确处理 null,undefined 和各种类型的对象(包括包含 Symbol 属性的对象),且性能较好,具有较高的可靠性。