为什么在 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__()
}
👉 每个数组也是一个对象!
数组类型也不例外。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()
...
]
👉 它在 JavaScript 引擎中是如何实现的?
类似地,数组是 JavaScript 引擎中对象的一种特殊情况。
但它们具有以下特点:
- 指数的特殊处理
- 神奇的长度属性
要了解物体的工作原理,请查看我的文章。
👉 索引处理
数组索引用包含数字的字符串表示。
因此,数组中的每个元素都与一个数字字符串相关联。
👉 长度属性
长度是一个不可配置且不可枚举的属性。当数组中添加或删除元素时,JavaScript 引擎会自动更新其值。
PS:请在Twitter上关注我,获取更多类似内容!
文章来源:https://dev.to/fromaline/why-an-array-is-an-object-in-javascript-4bh6

