Reputation: 1581
Long time I write code in JavaScript, using jQuery, ReactJS and NodeJS server side (ExpressJS). I learned partially MDN and other sources, however there is one question I can not found an answer for.
Why follow code requires prototype
object's property? Why I can not use forEach
directly from Array
object? I mean, in terms of OOP, if Array
class extends class contains forEach
method, I can call it from object instantiated from Array
directly, I don't need, using reflection find base class, instantiate it and call the method from the base class.
Array.prototype.forEach.call(document.querySelectorAll('.klasses'), function(el){
el.addEventListener('click', someFunction);
});
Example taken from here: https://www.smashingmagazine.com/2014/01/understanding-javascript-function-prototype-bind/
Upvotes: 0
Views: 53
Reputation: 33726
querySelectorAll
doesn't return an Array, returns a NodeList
(like array-object) instead. The NodeList has a property called .length
that indicates the count of elements inside of it.
Some browsers/engines/backend techs are incompatible because that NodeList
no necessarally will provide the function forEach
.
So, an alternative is converting that NodeList
to an Array using the Array prototype:
Array.prototype.forEach.call(document.querySelectorAll('.klasses'), function(el){...})
Or, you can use the function Array.from
that will use the property .length
to create the array:
Array.from(document.querySelectorAll('.klasses'));
Although NodeList is not an Array, it is possible to iterate on it using
forEach()
. Several older browsers have not implemented this method yet. You can also convert it to an Array usingArray.from
.
Upvotes: 1
Reputation: 943510
Why I can not use forEach directly from Array object?
The Array object is a constructor function used to create arrays. It doesn't have a forEach
property of its own.
You can access the forEach
property either from an instance of Array (which you can create with new Array
or, more idiomatically, with []
), or by accessing the prototype
that gets applied to instances of Array.
Upvotes: 1
Reputation: 413720
Your code:
Array.prototype.forEach.call(document.querySelectorAll('.klasses'), function(el){
el.addEventListener('click', someFunction);
});
could indeed be written as
[].forEach.call(document.querySelectorAll('.klasses'), function(el){
el.addEventListener('click', someFunction);
});
Going through the Array prototype object is just a way to access the functions available to any array instance without having to actually create an array. Using one or the other is mostly a matter of preference, and though the second form does involve the creation of an array object, the performance implications are minimal.
Upvotes: 2