javascript - 数组键和填充

时间:2016-10-17 11:35:14

标签: javascript arrays

我发现js的以下行为有点奇怪,无法找出原因。

让我们假设以下代码:

var arrayName = new Array(15);
console.log(arrayName);

这将输出[undefined,undefined,undefined,...](未定义15次)。

现在让我们使用以下代码:

var arrayName = new Array(15).fill();
console.log(arrayName);

由于没有为fill提供参数,因此将输出(如预期的那样)[undefined,undefined,undefined,...](未定义15次)。

现在让我们在数组中添加一个循环(使用for in格式,而不是增量格式):

var arrayName = new Array(15);
console.log(arrayName);
for (var i in arrayName) {
    console.log(i);
}
  

这将不输出任何内容(不是我真正期望的原因 - 我希望数字从0到14)

现在让我们使用带有填充的代码:

var arrayName = new Array(15).fill();
console.log(arrayName);
for (var i in arrayName) {
    console.log(i);
}
  

这将输出0,1,2,...,14(在两种情况下我都期望)。

那么......为什么会有差异?

  

我认为索引不是在第一种情况下创建的(但仍然输出未定义的元素......为什么?)。这是语言不一致还是背后的一些逻辑?

P.S。将鼠标移到空白框上以查看内容。

2 个答案:

答案 0 :(得分:2)

基本上:不要在阵列上使用它! :http://ilikekillnerds.com/2015/02/stop-writing-slow-javascript/

for.in用于对象。甚至MDN也说明了这一点:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

创建数组并且它有一些索引,但由于没有任何实际数据(未定义),那么为什么会有任何键?

//The difference is in enumerable keys:

console.log(Object.keys(new Array(15))); //Produces no keys since no data is allocated
console.log(Object.keys(new Array(15).fill())); //Produces 15 keys

//What you probably want is to loop through the allocated places in the array, not the keys of it:
for(var i = 0; i < new Array(15).length; i++) {
  console.log(i)
}

为什么会这样?

你有没有试过Object.create

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

//Allocating a new object
var test = Object.create({}, {
  p: {
    value: 42
  }
});

//Logging object... but where is p?
console.log("where is p?",test);

//there it is :)
console.log("there it is",test.p);

//Lets try that again
test = Object.create({}, {
  p: {
    value: 42,
    enumerable: true
  }
});

//Logging object... and there is p
console.log("All good",test);

//New object values are non-enumerable by default. Also on Arrays

答案 1 :(得分:1)

var arrayName = new Array(15);
console.log(arrayName);
for (var i in arrayName) {
    console.log(i);
}

让我们看看上面发生的事情。

var arrayName = new Array(15);
  

如果传递给Array构造函数的唯一参数是整数   在0到232 ^ -1(包括)之间,这将返回一个新的JavaScript数组   长度设置为该数字。

所以这就是你在上面的例子中得到的。所以它是一个长度设置为15的空数组。现在你用于循环,迭代可枚举属性,并在每次迭代时为变量i分配不同的属性名称

console.log(arrayName.propertyIsEnumerable('length'));

返回false,因此您拥有的数组没有可枚举属性且为空数组。所以什么都没得到。

现在在第二种情况下,因为你使用了fill(),但你没有传递任何值作为第一个参数,用于填充数组。由于您没有传递任何值,因此整个数组都填充了undefined,数组索引定义为数组的长度。 (请参阅此处填充的构造函数https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/fill

另请注意“数组索引只是具有整数名称的可枚举属性”。

现在for循环遍历数组索引属性,并打印出打印0-14的值。

要了解更多信息,请https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in