I'm building an app with Babel/ES6. I want to disable all form elements for a view-only version of it, so I did this:
let form = document.getElementById('application-form')
let elements = form.elements
I expected to be able to do this, instead of using a regular old for
loop (which did work):
elements.forEach((el) => {
el.disabled = true
})
but I got TypeError: elements.forEach is not a function
The strange thing is if I console.log(elements)
in the Chrome dev console it exactly like an array with a bunch of input
objects. It doesn't display with the Object
notation for objects, and all of the keys are integers. I'm thinking it's some sort of pseudo array, but I wouldn't even know how to find that out.
EDIT: short answer it's not an array it's an HTMLCollection. see Why doesn't nodelist have forEach?
Per this answer, nodelist
now has the forEach
method!
The forEach method is also used to loop through arrays, but it uses a function differently than the classic "for loop". The forEach method passes a callback function for each element of an array together with the following parameters: Current Value (required) - The value of the current array element.
forEach() does not make a copy of the array before iterating.
JavaScript's Array#forEach() function lets you iterate over an array, but not over an object. But you can iterate over a JavaScript object using forEach() if you transform the object into an array first, using Object. keys() , Object. values() , or Object.
map() allocates memory and stores return values. forEach() throws away return values and always returns undefined . forEach() will allow a callback function to mutate the current array. map() will instead return a new array.
You can. You just can't use it like that, because there is no forEach
property on the HTMLFormControlsCollection
that form.elements
gives you (which isn't an array).
Here's how you can use it anyway:
Array.prototype.forEach.call(form.elements, (element) => {
// ...
});
Or on modern browsers you can make use of the fact that the underlying HTMLCollection
is iterable even though it doesn't have forEach
:
// `for-of`:
for (const element of elements) {
// ...do something with `element`...
}
// Spreading into an array:
[...elements].forEach((element) => {
// ...do something with `element`...
});
That won't work on obsolete browsers like IE11 though.
There's also Array.from
(needs a polyfill for obsolete browsers):
Array.from(elements).forEach((element) => {
// ...
});
For details, see the "array-like" part of my answer here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With