带有未定义的数字索引的javascript数组

时间:2013-04-01 19:51:05

标签: javascript arrays object

假设我这样做..

var arr = Array();
var i = 3333;
arr[i] = "something";

如果你对这个数组进行字符串化,它将返回一个字符串,其中包含一大堆未定义的数字条目,用于那些索引小于3333的条目......

有没有办法让javascript不这样做?

我知道我可以使用一个对象{}但是我不愿意,因为我想做一些像对象无法使用的数组操作,例如shift()等

2 个答案:

答案 0 :(得分:1)

如果按OP创建数组,则只有一个成员的属性名称为“333”,长度为334,因为长度始终设置为至少比最高索引大一个。例如

var a = new Array(1000);

的长度为1000,没有成员,

var a = [];
var a[999] = 'foo';

的长度为1000,其中一个成员的属性名称为“999”。

仅获取已定义成员的快速方法是使用for..in:

function myStringifyArray(a) {
  var s = [];
  var re = /^\d+$/;

  for (var p in a) {
    if (a.hasOwnProperty(p) && re.test(p)) {
      s.push(a[p]);
    }
  }
  return '' + s;
}

请注意,会员可能会无序退回。如果这是一个问题,你可以使用for循环,但对于非常稀疏的数组它会更慢:

function myStringifyArray(a) {
  var s = [];
  var re = /^\d+$/;

  for (var i=0, iLen=a.length; i<iLen; i++) {
    if (a.hasOwnProperty(i)) {
      s.push(a[i]);
    }
  }
  return '' + s;
}

在一些较旧的浏览器中,迭代数组实际上创建了缺少的成员,但我不认为这在现代浏览器中存在问题。

请彻底测试以上内容。

答案 1 :(得分:0)

数组的文字表示必须包含数组的所有项,否则第3334项不会以索引3333结束。

您可以将数组中的所有未定义值替换为您要用作空项的其他内容:

for (var i = 0; i < arr.length; i++) {
  if (typeof arr[i] == 'undefined') arr[i] = '';
}

另一种方法是构建自己的stringify方法,该方法将创建赋值而不是数组文字。即而不是像这样的格式:

[0,undefined,undefined,undefined,4,undefined,6,7,undefined,9]

你的方法会产生类似的东西:

(function(){
  var result = [];
  result[0] = 0;
  result[4] = 4;
  result[6] = 6;
  result[7] = 7;
  result[9] = 9;
  return result;
}())

然而,像这样的格式当然与JSON不兼容,如果这是你需要的。