HOWTO · JavaScript

JavaScript 中的字典长度

本文演示了如何在 JavaScript 中查找字典的长度。

本页内容

在 JavaScript 中,字典通常用对象表示,对象的属性将键映射到值。要获取它的长度,先要确定要统计哪些属性:JavaScript 对象没有内置的 length 属性,因此通常统计对象自身可枚举的字符串键属性。数组则不同:数组有内置的 length 属性,用来表示其索引长度。

JavaScript 中对象的“长度”是什么意思?

对象可以有自身属性、继承属性、可枚举或不可枚举属性,以及以 Symbol 为键的属性。对象没有一个内置的长度值可以统计所有这些属性。对于一般的字典,统计自身可枚举的字符串键是实用的默认做法。下面的方法统计范围相同;而 for...in 需要检查属性归属,以排除继承的可枚举键。

使用 Object.keys() 统计自身可枚举的字符串键

如果只需要数量或键列表,Object.keys(object).length 是简洁的选择。Object.keys() 会返回一个数组,其中包含对象自身可枚举的字符串键属性名称;该数组的 length 就是数量。继承属性、Symbol 键和不可枚举属性都不计入。

运行以下示例:

本节中的代码以及显示的标签或输出仍为英文。

const dictionary = {
  name: "John",
  age: 30,
  city: "New York"
};

console.log(Object.keys(dictionary).length);

这个表达式会统计对象中的三个键。这里提供的是代码示例,没有附上运行输出。若对象没有自身可枚举的字符串键,计数结果就是 0;因此,可以用 Object.keys(dictionary).length === 0 检查这类字典是否为空。

需要键值对时使用 Object.entries()

Object.entries(object).length 统计的自身可枚举字符串键属性,与 Object.keys(object).length 相同。区别在于,Object.entries() 返回由 [key, value] 组成的数组。当后续步骤需要键和值两部分时,例如格式化每个条目或转换其值,使用它会很方便;如果只需要计数,Object.keys() 更直接地表达了意图。

例如,给定 { name: "Alice", age: 25 },条目在概念上是 [["name", "Alice"], ["age", 25]],条目数组包含两个元素。这是在说明返回的数据结构,并不表示这里执行过代码。

使用 for…in 循环统计属性

for...in 循环会遍历对象及其原型链上的可枚举字符串键。如果要像上面的方法一样只统计自身属性,就需要对每个键进行检查。调用 Object.prototype.hasOwnProperty.call() 比调用 object.hasOwnProperty(key) 更安全:对象自身可能有一个名为 hasOwnProperty 的属性,从而遮蔽该方法。

本节中的代码以及显示的标签或输出仍为英文。

const dictionary = { name: "Bob", age: 40, city: "Chicago" };
let count = 0;

for (const key in dictionary) {
  if (Object.prototype.hasOwnProperty.call(dictionary, key)) {
    count++;
  }
}

console.log(count);

这个循环统计自身可枚举的字符串键,并跳过继承的可枚举键。准确地说,hasOwnProperty 是这里用于检查属性归属的术语。如果你需要在遍历每个键时执行操作,可以使用循环;否则,Object.keys() 或 Object.entries() 通常更简洁易读。

选择合适的方法并处理常见情况

如果要直接计数或同时获取键,请选择 Object.keys(object).length。如果除了计数还需要键值对,请选择 Object.entries(object)。如果手动迭代更适合周边逻辑,请选择带归属检查的 for...in 循环。这些方法说明了各自统计的范围,并不能据此断定某种方法在所有对象或工作负载下都更快。

嵌套对象在其父对象中仍然只是一个属性。例如,{ user: { name: "Sam" } } 只有一个顶层键 user;统计 user 内部的键是另一个操作。这些方法不会自动递归计数;若要递归计数,需要先明确要遍历哪些嵌套值。

数组本身已有 array.length,它表示数组的索引长度,也可能包含尚未赋值的位置。Object.keys(array).length 统计的则是数组自身的可枚举字符串键;如果数组存在空位或额外属性,它就不能替代数组长度。获取数组长度时使用内置属性;统计字典式对象的属性时使用对象键相关的方法。