使用JavaScript新的Array(n)声明

基本的JavaScript问题:因为对Java来说没有硬性的限制(例如IndexOutOfBoundsException ),那么声明中指定length属性的用法是什么?

var a = new Array(10); 

我知道它预先确定了长度,并将“未定义”放入这些空白点。 这就足够了吗?

声明一个数组的大小有很多好处,但是我认为大部分被感知的好处就是FUD被传递。

更好的performance!/更快!

据我所知,预分配和dynamic分配之间的差异可以忽略不计。

更有趣的是,规范并没有说明数组应该被设置为预先分配的长度!

从第15.4.2.2节ECMA-262 :

如果参数len是一个Number并且ToUint32( len )等于len ,则新构造的对象的length属性被设置为ToUint32( len )。 如果参数len是一个Number并且ToUint32( len )不等于len ,则会引发RangeErrorexception。

一个不科学的有趣的testing案例在这里: http : //jsbin.com/izini

它使更多的可以理解的代码!

我个人不同意。

考虑你以前写过的JavaScript,并考虑你以后可能需要写的代码。 我无法想象我需要在一个数组上指定一个静态限制。 我还认为在javascript中限制数组的潜在问题,大大超过了让人们知道你在想什么而没有实际检查的好处。 让我们权衡利弊

优点:

  1. 他们会更容易理解你想要的代码。
  2. 他们将能够find你后来的假设所造成的错误(舌头紧盯着脸颊)

缺点:

  1. 快速浏览可以很容易地混淆“新arrays(10)”和“新arrays('10')”做完全不同的事情!
  2. 您正在对代码施加任意的限制,没有正常的长度限制,导致您编写大量的锅炉代码来检查和维护限制。
  3. 你正在对代码施加任意的限制,这可能已经被推广到可以处理任何长度的值。
  4. 您假定人们会如何阅读您的代码,同时假设替代scheme不那么令人困惑。

你也可以写下:

 //I assume this array will always be length 10 var arr = new Array(); 

在上述情况下,评论甚至可能更可取。 明确的意图声明可以避免任何混淆,而不习惯使用构造函数作为意图声明。

那好..那你为什么觉得那里呢?

方便。 当他们写规格时,我认为他们意识到了两件事情。

  1. 这种分配将会是来自类似语言的开发者所习惯的。
  2. ECMAScript的实现可能会使用它来提高性能。

所以他们把它放在那里。 规范只定义了参数的使用,而不是如何实现。

V8 JavaScript引擎的性能。

通过做:

 var arr = []; arr.length = 1000; 

V8将为arrays预分配所需的内存,并将arrays的Hidden Class保持/设置为紧凑型SMI (小型Int,31位无符号) arrays 。 然而,当期望的长度太大时,这不是真的,这导致HC被设置为稀疏arrays (即,映射)。

在Chrome上尝试以下链接: http : //jsperf.com/0-fill-n-size-array

我已经包含了一个没有数组长度定义的额外的testing用例,所以你可以告诉实际的性能差异。

相关信息: http : //www.youtube.com/watch?v = UJPdhx5zTaw

我不确定,但我敢打赌,它分配不同的内存在一个较低的水平。 如果您知道自己创build了10,000个项目,只需预留足够的空间,而不是dynamic地将其大小调整为背景。

明晰。

在编写代码的时候,你的目标不是让计算机理解你,而是让下一个读你的代码来理解你的程序员。

 var xs = new Array(10); 

上面的代码显示了你的意图 :有一个10个元素的数组。

 var xs = []; 

上面没有提供任何东西; 没有额外的信息。

干杯。

我创build了这个JSPerf来演示这个问题,包括它的各种版本。 我发现的论点是这样的:

  1. 使用新的Array()可能会出现意外,可以被覆盖
  2. 设置.length并不会增加某些浏览器的数组大小
  3. 性能打击不是真的存在。

我认为这些testing应该把这些争论放在一边,但是应该指出的是,不同的浏览器对这个问题的处理方式有很大不同。 Firefox似乎会优化并计算出arrays的大小,而Chrome会像预期的那样分配内存。 而且,像往常一样,Internet Explorer只是在这个任务上发臭。

不难维护数组大小。 看看下面的例子:

 function updateArray(){ var a = [1,2,3,4,5,6,7,8,9,10]; //original array object var b = [11, 12, 13]; //New array object to be pushed a.splice(a.length-b.length, a.length); a.unshift.apply(a, b); return a; } 

a.unshift.apply(arg1, arg2)将顶部的新元素和顶部的a.unshift.apply(arg1, arg2)推到底部。

那么,我个人想要一个队列。 我想排队长度为10。

最简单的方法是使用push数组方法将项目放到队列的末尾,使用shift()方法将它们从数组的前面移开。

问题是,如果我想对我的队列做一个简单的“添加”方法,我就这样写:

 function addItemToArray(item, array){ array.shift(); array.push(item); return array; } 

那么没有好事发生。 什么更好(实际上,将工作)是这样的声明我的数组:

 var maxSizeIsTen = new Array(10); 

然后到处使用它。 另外,请注意描述数组的“很好”的方式 – 没有人读的注释,任何使用这个代码的人都可以在短时间内完成这个数组的最大尺寸。

好极了!