这里我有一个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;
答案 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个未定义元素的数组。但是阵列中的存储是预先分配的。这被认为是处理数组的更有效方式。如果您事先知道阵列长度,请始终使用此方法。 (顺便说一句,让数组的所有元素具有相同的类型更为有利)
如果您预先分配数组,请不要将元素推送到它。为数组中的元素赋值,如下所示:
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;
如果您事先不知道数组大小,请创建一个空的零长度数组,push
(或unshift
,push
将一个元素放入数组的最后一个位置,unshift
将元素放入数组中的第一个0索引位置。这种方法效果较慢,因为每次push或unshift都会动态地改变数组的大小。