使用数组括号表示法时,javascript引擎盖下发生了什么

时间:2018-05-21 18:12:42

标签: javascript arrays operators

我一般发现javascript是透明的,因为很少有黑盒子,其中"魔法"只是发生了,你应该接受并看看另一种方式,但是我没有找到任何答案,如果数组括号[]符号实际上是如何工作的。

let arr = [4, 5, 6, 7]
console.log(arr[3]) // <- How does this work?

javascript正在做什么来访问索引3处的项目。它是否在内部调用Array.prototype上的某个方法?

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

let obj = {
  a: 'hello',
  b: 'world'
}
obj['a'] === obj.a // true

数组是否只是一个具有长整数属性列表的对象?

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

我已经看到很多在线讨论都得出结论,你不能将括号表示法重载为真正的子类化数组但我从未见过关于允许数组工作的引擎盖下发生什么魔法的解释它的方式。

明显的后续问题是,是否有任何方法可以截取括号表示法来定义自己的行为,但我想我已经知道了答案。

2 个答案:

答案 0 :(得分:2)

您可能必须查看实现代码才能准确了解正在发生的事情,但基本思路是数组实际上是在对象上分层。

这是倒退:

  

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

括号表示法更为基础。因此,obj['foo']obj.foo的工作方式相同,但obj['foo & bar']没有等效的,这是完全合法的,并且如果obj有一个名为的密钥,则会回复一个值"foo & bar"

  

数组是否只是一个具有长整数属性列表的对象?

不完全,但你不远了。数组是具有Array原型的对象,并且在添加新密钥时可以设置length属性,或者在设置length时删除密钥。

不,您不能为了自己的目的而覆盖[]运算符。

答案 1 :(得分:1)

  

数组是否只是一个具有长整数属性列表的对象?

是的,在它最简单的形式中,Array是一个Object,它包含一个基于Array原型的整数基本属性列表(可以访问所有数组方法,如map,forEach等)

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

来自MDN的更多信息:

  

数组是类似列表的对象,其原型具有执行遍历和变异操作的方法。 JavaScript数组的长度和元素的类型都不固定。由于数组的长度可以随时改变,并且数据可以存储在数组中的非连续位置,因此不能保证JavaScript数组密集;这取决于程序员如何选择使用它们。一般来说,这些都是方便的特征;但如果这些功能不适合您的特定用途,您可以考虑使用类型化数组。

     

数组不能使用字符串作为元素索引(如在关联数组中),但必须使用整数。使用括号表示法(或点表示法)通过非整数设置或访问不会从数组列表本身设置或检索元素,而是设置或访问与该数组的对象属性集合关联的变量。数组的对象属性和数组元素列表是分开的,并且数组的遍历和变异操作不能应用于这些命名属性。