我正在挖掘jQuery源代码,我发现他们使用这个小代码片段来检测JavaScript对象是否为空。
function isMyObjEmpty( obj ) {
var name;
for (name in obj ) {
return false;
}
return true;
}
有人能解释一下为什么会这样吗?我只是不明白为什么会永远这样。
答案 0 :(得分:17)
这使用for... in
循环来遍历对象的属性。
如果对象具有任何属性,它将进入循环并返回false
如果对象没有属性,则不会进入循环,并返回true
。
请注意,存在不起作用的情况。 for.. in
循环仅通过enumerable
属性,因此从技术上讲,对象可以是非空的,但仍然会返回false。可以define a property不能枚举并欺骗这种方法。 Here is the problematic case
正确的说法是,此方法会检查对象是否具有可枚举属性。
您可以找到该方法的documentation here。
描述:检查对象是否为空(不包含可枚举的属性)。
我个人觉得很奇怪他们会称这种方法为isEmptyObject
。我认为一个更合适的名字是hasNoEnumerableProperties
。
在JS的较新实现中,可以使用Object.getOwnPropertyNames
。 getOwnPropertyNames
获取所有属性,可枚举与否。
您可以使用isMyObjEmpty
实施Object.getOwnPropertyNames(myObject).length===0
。这将检查对象是否没有可枚举的属性。
但是,这并不会检查原型属性。这可能是,也可能不是理想的行为,您可以查看我对theshadowmonkey的讨论。这可以通过递归调用Object.getPrototypeOf
并检查原型链中的属性来轻松解决。
答案 1 :(得分:1)
如果它在name
中找到obj
,那么obj中有一些东西并且它不是空的,如果它不能这样做它会返回true,说obj是空的
答案 2 :(得分:0)
试试这个。我认为这是因为对象自己的属性。您需要hasOwnProperty以确保不访问其原型属性。
function isMyObjEmpty( obj ) {
var name;
for (name in obj ) {
if(obj.hasOwnProperty(name)) {
return false;
}
}
return true;
}
阅读文档并查看其中的含义。
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/for...in
答案 3 :(得分:0)
也许不是,但我假设混淆来自obj中的关键“名字”。它实际上并不是在对象中查找名为name的键,而是将对象中的任何键分配给它们名为name的变量。因此,如果它在对象中找到任何内容,它将返回false并确认它确实不是空对象。但如果它在对象中找不到任何内容,它将返回true,表示您的对象为空。
答案 4 :(得分:0)
关键是for..in循环迭代对象的每个属性,但没有别的。如果对象中根本没有任何内容,那么该循环将永远不会运行,因此“return false”行永远不会被执行。程序然后转到下一行,告诉它返回true。
(这导致一个有趣的问题本身。那个for..in循环是否应该包含在hasOwnProperty()检查中?或者该函数是否实际上打算捕获非自己的属性并在此基础上将对象计为非空?)
答案 5 :(得分:-1)
当对象为空时,它什么时候会返回true。
isMyObjEmpty({});
它是如何工作的?使用for...in
用于...在
摘要的
以任意方式迭代对象的可枚举属性 订购。对于每个不同的属性,可以执行语句。
因此,如果没有属性,它将不会进入for循环。该循环确实应该检查hasOwnProperty()
,因为这可能导致误报。