这个问题已经在这里有了答案:
已关闭8年。
我目前正在学习JavaScript,并且已经阅读了一些简单的介绍和教程。在查看Array对象时,我偶然发现了一些细节,这些细节使我感到非常奇怪,它们来自其他语言,例如C / Java / Scala / ...
因此,假设我们这样定义一个数组:
var arr = ['foo','bar','qux']
现在,我们分配
arr[5] = 'baz'
这导致我们的数组如下所示:
arr
>> ["foo", "bar", "qux", undefined, undefined, "baz"]
和长度一样
arr.length
>> 6
JavaScript已将数组扩展为所需的长度-六个-并且将新项目设置为undefined-除了我们实际为其分配值的那个。
从低级的 Angular 来看,这在内存方面是可怕的。通常,阵列将是内存中的连续范围-使阵列变大通常涉及将整个阵列复制到足够大的新存储位置。这是非常昂贵的操作。
现在,我确实意识到这很可能是javascript引擎在做的而不是,因为在数组周围复制会非常昂贵,并且所有这些“未定义”的值都会浪费内存空间。
有人可以告诉我门后到底发生了什么吗?
最佳答案
在JavaScript的第一个版本中,没有数组。后来,它们被作为“所有对象之母”的子类引入:Object
。您可以通过执行以下操作很容易地对此进行测试:
var foo = [1,2,3,4];
for (var n in foo)
{//check if n is equal (value and type) to itself, coerced to a number
console.log(n === +(n) ? 'Number' : 'String');
}
这将再次记录
String
。在内部,所有数字键都转换为字符串。 Length属性仅获取最高索引,并将其加1。而已。当显示数组时,对象被迭代,并且对于每个键,适用于任何对象的规则:首先扫描实例,然后扫描原型(prototype)……因此,如果我们稍微修改一下代码:var foo = [1,2,3,4];
foo[9] = 5;
for (var n in foo)
{
if (foo.hasOwnProperty(n))
{//check if current key is an array property
console.log(n === +(n) ? 'Number' : 'String');
}
}
您会注意到该数组仅具有5个自己的属性,
undefined
键4-8是未定义的,因为在实例中或任何底层原型(prototype)中均未找到对应的值。简而言之:数组并不是真正的数组,但是对象的行为类似。正如Tim所言,您可以拥有该对象中确实存在未定义属性的数组实例:
var foo = [1,2,undefined,3];
console.log(foo[2] === undefined);//true
console.log(foo[99] === undefined);//true
但还是有一个区别:
console.log((foo.hasOwnProperty('2') && foo[2] === undefined));//true
console.log((foo.hasOwnProperty('99') && foo[99] === undefined));//false
回顾一下,您的三个主要问题:
undefined
值,它们只是JS扫描对象和原型(prototype)而找不到您要查找的内容时的默认返回值:“抱歉,您问我的内容在我的书中未定义。”就是这样更新:
只是quoting the Ecma std:
关于javascript - JavaScript数组的内存管理,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12640216/