在javascript中,当使用数组括号表示法时,会发生什么

在javascript中,当使用数组括号表示法时,会发生什么,javascript,arrays,operators,Javascript,Arrays,Operators,我通常认为javascript是透明的,因为很少有黑匣子会发生“魔法”,你应该接受并从另一个角度看,但是我没有找到任何答案来解释数组括号[]符号在引擎盖下是如何工作的 let arr = [4, 5, 6, 7] console.log(arr[3]) // <- How does this work? 那么,数组是否只是一个具有一长串基于整数的属性的对象 let objArray = { 0: 'hello', 1: 'world' } let realArray = ['

我通常认为javascript是透明的,因为很少有黑匣子会发生“魔法”,你应该接受并从另一个角度看,但是我没有找到任何答案来解释数组括号
[]
符号在引擎盖下是如何工作的

let arr = [4, 5, 6, 7]
console.log(arr[3]) // <- How does this work?
那么,数组是否只是一个具有一长串基于整数的属性的对象

let objArray = {
   0: 'hello',
   1: 'world'
}
let realArray = ['hello', 'world']

objArray[0] === 'hello' // true
realArray[0] === 'hello' // true

objArray.0 // SyntaxError: Unexpected number
realArray.0 // SyntaxError: Unexpected number
我在网上看到过很多讨论,都得出这样的结论,即不能通过重载方括号符号来真正对数组进行子类化,但我从来没有看到过一个解释,说明在引擎盖下发生了什么神奇的事情,使数组能够按它的方式工作

接下来一个明显的问题是,是否有任何方法可以拦截括号符号访问来定义您自己的行为,但我想我已经知道了答案

那么,数组是否只是一个具有一长串基于整数的属性的对象

let objArray = {
   0: 'hello',
   1: 'world'
}
let realArray = ['hello', 'world']

objArray[0] === 'hello' // true
realArray[0] === 'hello' // true

objArray.0 // SyntaxError: Unexpected number
realArray.0 // SyntaxError: Unexpected number
是的,在最简单的形式中,数组是一个对象,具有基于数组原型的整数基属性列表(它提供对所有数组方法的访问,如map、forEach等)

至于截取括号表示法,不,除了创建自己的对象,该对象具有所需的方法(然后仅通过适当的方法访问该对象),我还没有看到任何允许截取括号表示法的内容

来自MDN的更多信息:

数组是类似列表的对象,其原型具有执行遍历和变异操作的方法。JavaScript数组的长度和元素的类型都不是固定的。由于数组的长度可以随时更改,并且数据可以存储在数组中的非连续位置,因此JavaScript数组不能保证密集;这取决于程序员选择如何使用它们。一般来说,这些都是方便的特性;但是,如果这些特性对于您的特定用途不可取,您可以考虑使用类型化数组。 数组不能使用字符串作为元素索引(如在关联数组中),但必须使用整数。使用括号表示法(或点表示法)通过非整数进行设置或访问不会从数组列表本身设置或检索元素,但会设置或访问与该数组的对象属性集合关联的变量。数组的对象属性和数组元素列表是分开的,数组的遍历和变异操作不能应用于这些命名属性


您可能需要查看实现代码才能准确了解发生了什么,但基本思想是数组实际上是在对象上分层的

这是倒退的:

对于对象,[]是属性访问器的快捷方式

let obj = {
  a: 'hello',
  b: 'world'
}
obj['a'] === obj.a // true
括号表示法更为基本。因此,
obj['foo']
obj.foo
的工作原理是一样的,但是对于
obj['foo&bar']
没有等价物,这是完全合法的,如果
obj
有一个名为
“foo&bar”
的键,它将以一个值响应

那么,数组是否只是一个具有一长串基于整数的属性的对象

let objArray = {
   0: 'hello',
   1: 'world'
}
let realArray = ['hello', 'world']

objArray[0] === 'hello' // true
realArray[0] === 'hello' // true

objArray.0 // SyntaxError: Unexpected number
realArray.0 // SyntaxError: Unexpected number
不完全是,但你离得不远。数组是具有
数组
原型的对象,在添加新键时,数组具有一点额外的魔力来设置
长度
属性,或者在设置
长度
时删除键


不,您不能为自己的目的重写
[]
运算符。

[]
是一个运算符。我想如果你能让操作员超负荷工作,你就能定制引擎盖下发生的事情。我想,
objArray.0'
可以工作,因为键是一个字符串,但是尝试之后,它就不工作了。但是,使用它作为键确实有效:
objArray[0]===objArray['0']
“javascript如何访问索引3处的项?”什么都没有;它只是访问索引。除此之外的所有内容都是底层JS引擎的一部分,并且可能会有所不同,这取决于此特定引擎用于存储此特定阵列的数据结构。因为即使这样(数组的底层数据结构)也可能因数组中的当前数据以及该数组所经历的更改而有所不同。您希望通过重载属性访问实现什么行为?@Thomas创建链表就是一个例子。在javascript中,我可以创建我喜欢的列表结构,比如说它是一个es6类。然后,我可以定义一个
符号。迭代器
,以便在
for…of
循环中使用我的新列表实例,或使用扩展运算符
…list
或在解构
中让[a,b,c]=list
。出于所有目的,我有一个很好的新数据类型。我不能做的一件事是使用括号符号来访问各个bucket。我希望能够执行类似于
符号的操作。迭代器
,这样我就可以为
list[0]
etcOOP定义我自己的行为:其中所有内容的核心都是一个对象“是一个数组,然后只是一个具有一长串基于整数的属性的对象?”->“不完全是,但离你不远了。”。在最坏的情况下,一个包含混合类型内容的稀疏数组,一个数组可以完全按照它存储,一个包含一长串基于整数的属性的字典。。。它仍然需要访问
Array.prototype
方法,并且必须能够使用
length
实现神奇的效果。但其基本结构很可能是一本词典。