发布于 2026-01-06 2 阅读
0

为什么在 JavaScript 中数组也是对象?

为什么在 JavaScript 中数组也是对象?

JavaScript 是一种基于原型的语言,因此只有基本类型和对象。这赋予了它灵活性,但同时也让事情变得更加复杂。

👉一切皆为物!

JavaScript 中所有非原始值的实现都是基于对象的。
简而言之,JavaScript 只有一个原型对象,所有其他对象都从中获取初始属性。我们可以通过访问该原型对象来获取它__proto__



Object.getPrototypeOf(Object).__proto__;
Object.getPrototypeOf(Array).__proto__;
Object.getPrototypeOf(Boolean).__proto__;

// The prototypical object of every object
{
  constructor: ƒ Object()
  hasOwnProperty: ƒ hasOwnProperty()
  isPrototypeOf: ƒ isPrototypeOf()
  propertyIsEnumerable: ƒ propertyIsEnumerable()
  toLocaleString: ƒ toLocaleString()
  toString: ƒ toString()
  valueOf: ƒ valueOf()
  __defineGetter__: ƒ __defineGetter__()
  __defineSetter__: ƒ __defineSetter__()
  __lookupGetter__: ƒ __lookupGetter__()
  __lookupSetter__: ƒ __lookupSetter__()
  __proto__: (...)
  get __proto__: ƒ __proto__()
  set __proto__: ƒ __proto__()
}


Enter fullscreen mode Exit fullscreen mode

👉 每个数组也是一个对象!

数组类型也不例外。Array全局类是一个全局对象,而数组字面量只是Array全局类的一个实例。
反过来,数组类型的直接原型包含了它的所有特殊方法,例如 fill、find 等。



// true
Object.getPrototypeOf(Array).__proto__ === Object.getPrototypeOf(Object).__proto__
Object.getPrototypeOf([]).__proto__ === Object.getPrototypeOf(Object).__proto__


Object.getPrototypeOf([])
[
  at:  ƒ at()
  concat:  ƒ concat()
  constructor:  ƒ Array()
  copyWithin:  ƒ copyWithin()
  entries:  ƒ entries()
  every:  ƒ every()
  fill:  ƒ fill()
  filter:  ƒ filter()
  find:  ƒ find()
  findIndex:  ƒ findIndex()
  findLast:  ƒ findLast()
  findLastIndex:  ƒ findLastIndex()
  flat:  ƒ flat()
  ...
]


Enter fullscreen mode Exit fullscreen mode

👉 它在 JavaScript 引擎中是如何实现的?

类似地,数组是 JavaScript 引擎中对象的一种特殊情况。
但它们具有以下特点:

  • 指数的特殊处理
  • 神奇的长度属性

要了解物体的工作原理,请查看我的文章

👉 索引处理

数组索引用包含数字的字符串表示。
因此,数组中的每个元素都与一个数字字符串相关联。

索引处理

👉 长度属性

长度是一个不可配置且不可枚举的属性。当数组中添加或删除元素时,JavaScript 引擎会自动更新其值。

长度属性


PS:请在Twitter上关注我,获取更多类似内容!

文章来源:https://dev.to/fromaline/why-an-array-is-an-object-in-javascript-4bh6