简体   繁体   中英

javascript - array keys and fill

I find the following behavior of js a bit strange and can't find out why this is happening.

Lets assume the following code:

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

This will output [undefined, undefined, undefined, ... ] (undefined 15 times).

Now lets use the following code:

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

Since no argument was supplied for fill, this will output (as expected) [undefined, undefined, undefined, ... ] (undefined 15 times).

Now lets add a loop through the array (using the for in format, not the incremental one):

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

This will output nothing (not really why I would expect - I would expect numbers from 0 to 14)

Now lets use the code with fill:

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

This will output 0, 1, 2, ..., 14 (what I would expect in both cases).

So... why the difference?

I think the indexes are not created in the first case (but still the undefined elements are output... why?). Is this a language inconsistency or is some logic behind it?

PS Move mouse over blank boxes to see content.

Basically: DONT USE FOR.IN ON ARRAYS! : http://ilikekillnerds.com/2015/02/stop-writing-slow-javascript/

for.in is for objects. Even MDN states this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

The array is created and it has some indexes, but since there isn't any real data (undefined), then why would there be any keys?

 //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) } 

Why is this?

Have you ever tried 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 

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

Let's see what happened in the above case.

var arrayName = new Array(15);

If the only argument passed to the Array constructor is an integer between 0 and 232^-1 (inclusive), this returns a new JavaScript array with length set to that number.

So this is what you got in the above case. So it's an empty array with length set to 15. Now you used for in loop,which iterates over enumerable property, and a different property name is assigned to variable i on each iteration

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

This returns false, so the array you have has no enumerable property and is an empty array. So you get nothing.

Now in the second case, since you used fill(), but you passed no value as the first argument, which is used to populate the array. Since you passed no value, the whole array was filled with undefined, with array indexes defined till the length of the array. ( See the constructor for fill here https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/fill )

Also note "Array indexes are just enumerable properties with integer names".

Now the for in loop iterated over the array index property, and printed the value of them which prints 0-14.

For more understanding, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM