Olga Pshenichnikova
Olga Pshenichnikova

Reputation: 1581

Why I need JavaScript prototype in extending object?

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

Answers (3)

Ele
Ele

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'));

From MDN docs

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 using Array.from.

Upvotes: 1

Quentin
Quentin

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

Pointy
Pointy

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

Related Questions