新的Array(20)实际上做了什么

时间:2014-10-02 13:00:32

标签: javascript arrays

这里我有一个Store构造函数,它有一个名为arr的属性,使用new Array(height * width)创建,提供的高度和长度作为参数发送到Store构造函数。我知道新的Array(20)将创建一个数组,可以包含20个元素。

Store构造函数有一个prototype属性,它使用一个map数组并填充新Store实例的this.arr。

但令人惊讶的是,数组长度在填充过程之后得到扩展。它变成了40.我知道push方法在数组的末尾插入元素。这意味着数组已经有20个元素。但它应该是空的,对吧?我很困惑!!!



var map=['d d d d d ',
         'e e e e e ']
function Store(width,height){
    this.width=width;
	this.height=height;
	this.arr=new Array(this.width*this.height);
}
Store.prototype.set=function(map){
    for(i=0;i<this.height;i++){
	    for(j=0;j<this.width;j++){
		    this.arr.push(map[i][j]);
		}
	}
}
var store=new Store(map[0].length,map.length);
document.write('previously : '+store.arr.length+'</br>');
store.set(map);
document.write('now : '+store.arr.length);
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:2)

使用Array构造函数创建数组时,它会创建一个指定长度的稀疏数组。所以当你说Array(20)时,它已经创建了一个包含20个元素的数组(通过更改length属性),其中尚未定义。因此,假设长度设置为5,并且您尝试在0处访问元素。现在,JavaScript将在Array对象中查找属性0,它将找不到任何内容。因此,它将返回undefined。但是,当您执行类似array[0] = 1的操作时,它会分配属性0,值为1.因此下次当您查找array[0]时,它将返回1.实际上,当您只是创建一个数组,其中没有任何内容。

关于push,引自MDN's Array.prototype.push

  

push()方法将一个或多个元素添加到数组的末尾,并返回数组的新长度。

因此,无论何时推送数据,它都会扩展数组。你可能想做这样的事情

this.arr[i][j] = map[i][j];

答案 1 :(得分:1)

new Array(20)创建一个包含20个未定义元素的数组。但是阵列中的存储是预先分配的。这被认为是处理数组的更有效方式。如果您事先知道阵列长度,请始终使用此方法。 (顺便说一句,让数组的所有元素具有相同的类型更为有利)

如果您预先分配数组,请不要将元素推送到它。为数组中的元素赋值,如下所示:

&#13;
&#13;
var map=['d d d d d ',
         'e e e e e ']
function Store(width,height){
    this.width=width;
	this.height=height;
	this.arr=new Array(this.width*this.height);
}
Store.prototype.set=function(map){
    for(i=0;i<this.height;i++){
	    for(j=0;j<this.width;j++){
		    this.arr[i*j+j] = map[i][j];
		}
	}
}
var store=new Store(map[0].length,map.length);
document.write('previously : '+store.arr.length+'</br>');
store.set(map);
document.write('now : '+store.arr.length);
&#13;
&#13;
&#13;

如果您事先不知道数组大小,请创建一个空的零长度数组,push(或unshiftpush将一个元素放入数组的最后一个位置,unshift将元素放入数组中的第一个0索引位置。这种方法效果较慢,因为每次push或unshift都会动态地改变数组的大小。