推荐答案
-- -------------------- ---- ------- -------- ------------------ - -- ---- -- ----- - ------ ----- -- ---- - --------- ---- ---- - -- ------- --- --- --------- - ------ ------ -- -------------- - --- ---- --- -- ---- - -- ------------------- ----- - ------ ------ -- -------------- - - ------ ----- -- --------------------- -
本题详细解读
概念理解
“空对象”指的是不包含任何自身属性的对象。原型链上的属性不应被考虑。
常见的错误方法与问题
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 属性的对象),且性能较好,具有较高的可靠性。