我发现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。将鼠标移到空白框上以查看内容。
答案 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