与数组不同,获取对象长度总是很棘手的。
有两种方法获取对象长度:
-  
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 属性。我们需要知道,仅 string 和 arrays 具有属性 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.keys 与 Object.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.keys 和 Object.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

京公网安备 11010502036488号