Ignus
Ignus

Reputation: 139

output array length greater than input array after for in loop (undefined values)

Here's my html:

<div id='test'>
<input name="M1" size="3" value="1">
<input name="M2" size="3" value="2">
<input name="M3" size="3" value="3">
</div>

here's my javascript:

var test = document.getElementById('test');
var arr = test.querySelectorAll('input');
var arr2 =[];
for (i in arr) {arr2.push(arr[i].value) ;}

this my final array arr2:

["1","2","3",undefined,undefined,undefined,undefined,undefined,undefined]

the point is that arr.length is 3 but arr2.length is 9, six elements are undefined. Could you please explain why and better way to achieve it?

Upvotes: 0

Views: 34

Answers (2)

Nafeo Alam
Nafeo Alam

Reputation: 4692

forEach should work:

var test = document.getElementById('test');
var arrInput = test.querySelectorAll('input');
var arr2 = [];

arrInput.forEach(element => {
    arr2.push(element.value);
})
console.log(arr2)
<body>
    <div id='test'>
        <input name="M1" size="3" value="1">
        <input name="M2" size="3" value="2">
        <input name="M3" size="3" value="3">
    </div>
</body>

Upvotes: 0

Nick Parsons
Nick Parsons

Reputation: 50674

A for..in loop in JavaScript loops over the enumerable properties of an object. Here, you are trying to use for..in on arr, which is not an array, it's a NodeList (as that's the return value of querySelectorAll).

A NodeList has the enumerable properties of:

0
1
2
length
item
entries
forEach
keys
values

As you can see, it doesn't just contain the indexes of arr, but rather all the enumerable properties. This means your for..in loop will go through each of these. That's why you get undefined in your array as arr['length'].value for example will give you undefined. For looping a NodeList, you can use a regular for loop, a for..of loop or NodeList.prototype.forEach():

const test = document.getElementById('test');
const nodes = test.querySelectorAll('input');
const arr2 = [];
for (const input of nodes) {
  arr2.push(input.value);
}
console.log(arr2);
<div id='test'>
  <input name="M1" size="3" value="1">
  <input name="M2" size="3" value="2">
  <input name="M3" size="3" value="3">
</div>

As a side note, if you're trying to build an array of values from your inputs, you can use Array.from() with a mapping function on your NodeList like so:

const test = document.getElementById('test');
const nodes = test.querySelectorAll('input');
const arr2 = Array.from(nodes, ({value}) => value);
console.log(arr2);
<div id='test'>
  <input name="M1" size="3" value="1">
  <input name="M2" size="3" value="2">
  <input name="M3" size="3" value="3">
</div>

Upvotes: 1

Related Questions