为什么具有非常高的索引号的javascript数组导致崩溃/减速/故障?

Tos*_*kan 6 javascript node.js express

基本上破坏我的节点js express服务器的代码是这样的:

resultArr = [];
resultArr["test"] = [];
resultArr["test"][2015073012] = someObject;
Run Code Online (Sandbox Code Playgroud)

当我把它改成这个时,它运行没有问题

resultArr = [];
resultArr["test"] = {};
resultArr["test"][2015073012] = someObject;
Run Code Online (Sandbox Code Playgroud)

我在循环中做了这样的工作.

为什么它会破坏我的应用程序?

Mic*_*ary 7

正如您所发现的,您不应该为此使用数组,您应该使用对象.但是你应该更进一步,并使用一个对象作为顶级.由于您的2015073012值将用作字符串,因此从一开始就将其设为一个是一个好习惯:

var results = {};
results.test = {};
results.test['2015073012'] = someObject;
Run Code Online (Sandbox Code Playgroud)

要么:

var results = {};
results['test'] = {};
results['test']['2015073012'] = someObject;
Run Code Online (Sandbox Code Playgroud)

现在,您在任何JavaScript引擎中都不会有任何问题.

(顺便说一句,我将名称改为resultArr,results所以名称不会让它听起来像是一个数组.)

JavaScript数组是,你有这样的顺序输入的情况下array[0],array[1],array[2]等当你有钥匙任意字符串或任意大的数字,不要使用数组,使用对象.

不要被其他语言(如PHP)混淆,这些语言具有单一array类型,既可作为顺序0,1,2,3,...数组,也可作为键值对的字典.JavaScript具有数组和对象:对于顺序用例使用数组,对键值用例使用对象.

回到你的问题,为什么这个代码突破:

resultArr = [];
resultArr["test"] = [];
resultArr["test"][2015073012] = someObject;
Run Code Online (Sandbox Code Playgroud)

一种可能的解释是,当您为[2015073012]数组索引赋值时,JavaScript引擎正在执行您告诉它要执行的操作:它创建一个包含2,015,073,013个条目的数组(比您给出的值多一个,因为数组索引从0开始) .这是阵列中超过20亿个条目!您可能会看到这会导致问题 - 而且肯定不是您的意图.

其他引擎可能会意识到这是一个非常大的数字,并将其视为字符串而不是数字,就好像您首先使用的是对象而不是数组.(JavaScript数组也是一个对象,可以有键值对和数字索引.)

实际上,我在最新版Chrome中的JavaScript控制台中尝试了这一点,并且没有问题:

a = [];
a[2015073012] = {};
Run Code Online (Sandbox Code Playgroud)

但你没有那么幸运.在任何情况下,您都应该始终使用对象而不是数组来进行此类使用,以确保将它们视为键值对,而不是创建具有大多数空元素的大型数组.