Reputation: 139
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
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
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 value
s 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