8

我正在挖掘 jQuery 源代码,发现他们使用这个小代码片段来检测 JavaScript 对象是否为空。

function isMyObjEmpty( obj ) {
    var name;
    for (name in obj ) {
        return false;
    }
    return true;
}

有人可以向我解释为什么会这样吗?我只是不明白为什么这会返回真实。

4

6 回答 6

17

为什么有效:

这使用for... in循环来遍历对象的属性。

如果对象有任何属性,它将进入循环并返回false

如果对象没有属性,则不会进入循环,并返回true

为什么没有:

请注意,存在不起作用的情况。for.. in循环只通过enumerable属性,所以从技术上讲,一个对象可以是非空的,它仍然会返回 false。可以将属性定义为不可枚举并欺骗此方法。这是有问题的案例

正确的说法是这个方法检查一个对象是否有任何可枚举的属性。

文档怎么说:

您可以在此处找到该方法的文档

描述:检查对象是否为空(不包含可枚举的属性)。

我个人觉得他们会调用那个方法很奇怪isEmptyObject。我认为更合适的名字是hasNoEnumerableProperties.

如果你真的想检查一个对象是否为空怎么办?

在 JS 的较新实现中,可以使用Object.getOwnPropertyNames. getOwnPropertyNames获取所有属性,无论是否可枚举。

您可以isMyObjEmpty使用Object.getOwnPropertyNames(myObject).length===0. 这将检查对象是否没有可枚举的属性。

然而,这并没有检查原型属性。这可能是可取的行为,也可能不是可取的行为,您可以查看我与theshadowmonkey的讨论。这可以通过Object.getPrototypeOf递归调用并检查原型链中的属性来轻松解决。

于 2013-03-28T20:06:33.970 回答
1

如果它找到name了,obj那么 obj 中有东西并且它不为空,如果它不能这样做,它将返回 true,说 obj 是空的

于 2013-03-28T20:06:28.063 回答
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

于 2013-03-28T20:08:19.980 回答
0

也许不是,但我假设混淆来自于 obj.name 中的关键“名称”。它实际上并不是在对象中寻找名为 name 的键,而是将对象中的任何键分配给他们称为 name 的变量。因此,如果它在对象中找到任何东西,它将返回 false 并确认它确实不是一个空对象。但是如果它在对象中没有找到任何东西,它将返回 true 意味着您的对象是空的。

于 2013-03-28T20:09:44.853 回答
0

关键是 for..in 循环遍历对象的每个属性,但仅此而已。如果对象中没有任何内容,那么该循环将永远不会运行,因此“return false”行永远不会被执行。然后程序转到下一行,告诉它返回真。

(这本身就引出了一个有趣的问题。是否应该将 for..in 循环包含在 hasOwnProperty() 检查中?或者该函数实际上是否打算捕获非自己的属性并在此基础上将对象计为非空?)

于 2013-03-28T21:00:43.427 回答
-1

当对象为空时,它什么时候返回 true。

isMyObjEmpty({});

它是如何工作的?通过使用for...in


对于...在

概括

以任意顺序迭代对象的可枚举属性。对于每个不同的属性,可以执行语句。

所以如果没有属性,它就不会进入 for in 循环。循环确实应该检查,hasOwnProperty()因为这可能导致误报。

于 2013-03-28T20:06:35.920 回答