使用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中限制数组的潜在问题,大大超过了让人们知道你在想什么而没有实际检查的好处。 让我们权衡利弊
优点:
- 他们会更容易理解你想要的代码。
- 他们将能够find你后来的假设所造成的错误(舌头紧盯着脸颊)
缺点:
- 快速浏览可以很容易地混淆“新arrays(10)”和“新arrays('10')”做完全不同的事情!
- 您正在对代码施加任意的限制,没有正常的长度限制,导致您编写大量的锅炉代码来检查和维护限制。
- 你正在对代码施加任意的限制,这可能已经被推广到可以处理任何长度的值。
- 您假定人们会如何阅读您的代码,同时假设替代scheme不那么令人困惑。
你也可以写下:
//I assume this array will always be length 10 var arr = new Array();
在上述情况下,评论甚至可能更可取。 明确的意图声明可以避免任何混淆,而不习惯使用构造函数作为意图声明。
那好..那你为什么觉得那里呢?
方便。 当他们写规格时,我认为他们意识到了两件事情。
- 这种分配将会是来自类似语言的开发者所习惯的。
- 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来演示这个问题,包括它的各种版本。 我发现的论点是这样的:
- 使用新的Array()可能会出现意外,可以被覆盖
- 设置.length并不会增加某些浏览器的数组大小
- 性能打击不是真的存在。
我认为这些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);
然后到处使用它。 另外,请注意描述数组的“很好”的方式 – 没有人读的注释,任何使用这个代码的人都可以在短时间内完成这个数组的最大尺寸。
好极了!