如何在 JavaScript 中获取对象的长度

与数组不同,获取对象长度总是很棘手的。

有两种方法获取对象长度:

  • Object.keys 返回对象的所有可枚举属性键的数组。
  • 使用 Lodash 库的 _.size 方法
const object = { id: 1, status: 0 }

// 使用 JavaScript
Object.keys(object).length // 2

// 使用 Lodash
_.size(object) // 2

为什么我们不能调用对象 length

你可能想知道为什么我们不能直接调用对象 length 属性。让我们看看当我们这样做时会发生什么:

const object = { id: 1, status: 0 }

object.length // undefined

object.hasOwnProperty('length') // false

可以看到,它没有 length 属性。我们需要知道,仅 stringarrays 具有属性 length

const string = 'hello'
const array = [1, 2, 3]

string.hasOwnProperty('length') // true
array.hasOwnProperty('length') // true

什么是可枚举数

我在开头提到 Object.keys 返回一个可枚举属性键数组。所以,让我们找出 enumerable 属性的来源。

指定属性

通常,当我们要向对象添加属性时,我们可能只使用点符号:

const object = {}

object.id = 1

console.log(object) // { id: 1 }

定义属性

或者,我们也可以使用 Object.defineProperty,该方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

它接受 3 个参数:

  • obj — 要定义属性的对象。
  • prop — 要定义或修改的属性的名称或 Symbol
  • descriptor — 要定义或修改的属性描述符。
Object.defineProperty(obj, prop, descriptor)

让我们用这个方法定义一个属性:

const object = {}

Object.defineProperty(object, id, {
  value: 1
})

console.log(object) // {}

为什么是空的?为什么我们的属性没有出现?

那是因为当我们这样定义一个属性时,enumerable 属性的默认为 false。所以如果我们想让它出现,我们需要设置为 true

const object = {}

Object.defineProperty(object, id, {
  value: 1,
  enumerable: true // 
})

console.log(object) // { id: 1 }

可枚举默认为 true

让我们回到用点符号设置的对象属性示例。为什么它会自动显示?好吧,那是因为当我们这样分配属性时,enumerable 属性会自动设置为 true

const object = {}

object.id = 1

object.propertyIsEnumerable(id) // true

可枚举摘要

对于我们大多数人来说,在定义属性时很少触及可枚举属性。对于我们来说,这只是一种控制在使用 Object.keys 遍历对象时,创建的特定属性是显示还是隐藏的方法。

如果您想了解有关可枚举性的更多信息,可以 ECMAScript 6 中的可枚举性。

因此,enumerable 属性用于隐藏不应迭代的属性。这就是在 ECMAScript 1 中引入可枚举性的原因。

Object.keysObject.getOwnPropertyNames

现在您已经了解了 enumerable,让我们介绍另一个方法 Object.getOwnPropertyNames,您可以将其视为获取长度的选项。

const object = { id: 1 }

Object.defineProperty(object, status, {
  value: 0,
  enumerable: false
})

Object.keys(object) // ['id']
Object.getOwnPropertyNames(object) // ['id', 'status']

如您所见,object.getOwnPropertyNames 将返回所有属性键(即,可枚举和不可枚举属性),而 object.keys 只返回可枚举属性键。

如上所述,可枚举属性可能出于某种原因而被隐藏,因此您可能不想访问它。因此,Object.getOwnPropertyName 可能不是要用于获取对象长度的方法。

带 Symbols 类型的对象长度

object.keys 在默认情况下获取对象长度之前,我想再指出一个考虑因素。在 ES6 中,引入了一种新的数据类型,称为 symbol。它可以用作对象的属性名。

const user = {
  [Symbol('id')]: 1,
  status: 0
}

但问题是当你有一个 symbol 属性名时。Object.keysObject.getOwnPropertyNames 都不起作用。

Object.keys(user) // ["status"] <-- no symbol

Object.getOwnPropertyNames(user) // ["status"] <-- no symbol

因此,解决方案是使用 Object.getOwnPropertySymbols

Object.getOwnPropertySymbols(user) // [Symbol(id)]

现在结合这两种方法,您将得到适当的长度。

const enumerableLength = Object.keys(user).length
const symbolLength = Object.getOwnPropertySymbols(user).length

const totalObjectLength = enumerableLength + symbolLength // 2

你可能感兴趣的:(如何在 JavaScript 中获取对象的长度)