有没有一种方法可以从对象中获取元素数量?

7
让我详细解释一下。我手头有一个对象,如下所示 -
{
    "OBJECT1" : {
        "NAME1" : "VALUE1",
        "NAME2" : "VALUE2",
        "NAME3" : "VALUE3"
     },
     "OBJECT2" : {
        "NAME4" : "VALUE4",
        "NAME5" : "VALUE5"
     }
}

从这个对象中,我想要获取类似于 OBJECT1 中元素数量为 3,OBJECT2 中元素数量为 2 的信息。如果可能的话,使用 JavaScript。 基本上我想做的是动态地遍历对象中可用的名称值对,这样如果有人向对象添加另一个元素,我就不必更改我的代码。 另外,任何替代方案也被排除,因为在我的用例中只允许使用对象。

2
那些对象不称为 JSON 对象。JSON 只是一种表示 JavaScript 对象的标记。 - Marcel Korpel
1
@Marcel Korpel:那么,我们可以说这里看到的JSON字符串是JS对象的序列化形式吗? - Piskvor left the building
@Korpel - 是的,我也很想知道Piskvor问题的答案。因为在我们的项目中,我们将这些对象存储在“.json”文件中,并进行文件解析以在我们的JavaScript源代码中获取对象。因此,我认为这些被称为JSON对象。 - Sachin Shanbhag
1
@Piskvor和Sachin:正确。没有所谓的“JSON对象”。当这些JSON字符串被解析时,它们被“解释”为生成一个真正的(本地)JavaScript对象(请记住,JSON是“JavaScript对象表示法”的缩写)。这也是我删除了[json]标签的原因:这个问题确实涉及到一个JavaScript对象,它以JSON格式呈现给我们(这完全没有问题)。 - Marcel Korpel
还有一件事:你用我的姓来“呼叫”我,但这并没有通知到我。请阅读评论回复如何工作?以了解如何正确地进行操作。 - Marcel Korpel
显示剩余2条评论
3个回答

9

如果不转换对象,您可以通过以下方式遍历对象并计算属性:

function countObjectProperties(obj)
{
    var count = 0;
    for(var i in obj)
        if(obj.hasOwnProperty(i))
            count++;

    return count;
}

进一步阐述为什么需要使用hasOwnProperty,正如我在下面的评论中所说, 您可能会遇到一个问题,即库或浏览器已向对象添加了方法和属性,为了避免计算这些内容,我们在计数之前检查hasOwnProperty有关更多详细信息,请参见MSDNMozilla Developer Center


为什么 hasOwnProperty 是必要的(只是问问)? - KeatsPeeks
2
@Samuel_xL 你需要使用 hasOwnProperty 来避免计算函数和其他不需要的内置对象,这些对象可能是浏览器和/或插件添加的。 - Kristoffer Sall-Storgaard

4

对于表示对象的JSON字符串(这是您的情况),您不能使用任何长度属性。您需要遍历该对象(请参见Kristoffer S Hansen的答案)。

如果它表示一个数组,则可以使用以下方法获取其长度:

var len = arr.length;

JQuery使得它更简单:

var len = $(JSON).length;

2
请不要使用Jquery,并且在我的项目标准中应避免使用eval。 - Sachin Shanbhag
eval是针对数组示例的,但你不需要它。那只是额外的信息 :) 好的,我已经删除了eval,因为它与主题无关。 - KeatsPeeks
如果不必要,不要使用eval - Gumbo
目前,我的JSON对象只是像上面示例中的名称值对。我不确定是否可以循环遍历对象中的所有元素。以防万一不可能,那么也许我需要将名称值对移动到数组中,从那里我可以使用长度并进行循环。 - Sachin Shanbhag

1
为了回答你在问题中提出的更广泛的目标:
要循环遍历属性,可以使用for..in结构:
for (var item in myobject) {
  // some browsers add more properties to every object, we don't want those
  if (myobject.hasOwnProperty(item)) {
    do_something(item);
  }
}

假设myobject是您问题中的对象,这将循环遍历它并调用do_something(OBJECT1)do_something(OBJECT2);您可以使用相同的结构来循环遍历子对象:
// loop through OBJECT1 and OBJECT2
for (var item in myobject) {
  // some browsers add more properties to every object, we don't want those
  if (myobject.hasOwnProperty(item)) {
    // loop through the item's children
    for (var pair in item) {
      if (item.hasOwnProperty(pair)) {
        // each of the name:value pairs will be passed to this
        do_something_else(item,pair);
      }
    }
  }
}

在第二个片段中,似乎item已经是每个键值对的,因此再次对其进行迭代没有意义... - Timwi
@Timwi:实际上不是这样的:在外层循环中,我们遍历顶层属性,即OBJECT1和OBJECT2。 在内部循环中,我们遍历它们的属性,即NAME1、NAME2、NAME3和NAME4、NAME5。 如果嵌套更深,我们可以遍历更深的对象(也许可以使用递归)。 - Piskvor left the building
澄清一下,在第二个循环中,我正在迭代顶层对象的属性的属性(myobject.OBJECT1.NAME1等)。这种嵌套可能会更深,但在这种情况下不会。 - Piskvor left the building
对不起,由于某种原因,我以为你的第二个片段是第一个片段在循环中调用的do_something函数。没关系 :) - Timwi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接