1

In a tutorial I saw the following:

Array.from( template.querySelectorAll('.hw-text') )
  .forEach( n => n.textContent = hwMsg );

But the following line would also work.

template.querySelectorAll('.hw-text')
  .forEach( n => n.textContent = hwMsg );

Now I wonder why in the tuturial Array.from is used and what advantage you get from it.

Max Pattern
  • 1,430
  • 7
  • 18

3 Answers3

4

forEach was not part of the original NodeList specification. Browser support for querySelectorAll and Array.from is wider than for forEach on NodeLists.

Whether that additional browser support is worth it today is partly a matter of opinion and partly dependant on the website's target audience.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 1
    You can also polyfill it on `NodeList`, as I describe [in this answer](https://stackoverflow.com/questions/46057719/object-doesnt-support-this-property-or-method-ie10-11/46057817#46057817). :-) – T.J. Crowder Jun 07 '22 at 15:38
  • 1
    Just to be clear, the only browser these days that does not support this is Internet Explorer. If for some bizarre reason you are writing code for an organization that is still using Internet Explorer (some hospital administration code comes to mind), then you should use `Array.from` (as well as avoiding using pretty much anything after ES5) . In vast majority of circumstances these days, you do not need to support IE, and are free to use `forEach` on a NodeList. https://caniuse.com/mdn-api_nodelist_foreach – Stephen M Irving Jun 07 '22 at 15:38
  • What do you mean with: `partly dependant on the website's target audience.`? – Max Pattern Jun 07 '22 at 15:48
  • @MaxPattern — If your target audience is corporate users stuck on locked down networks that get browser updates once every three years then the browsers you need to aim to be compatible with are different than they would be if your target audience was people who buy a new smart phone and laptop every year. – Quentin Jun 07 '22 at 15:56
0

Element.querySelectorAll() returns a NodeList this object has a method called forEach which lets you to iterate over its items.

that same NodeList Object has length property, so you can pass it to Array.from which will return back an array, so you have access to all array methods and that's why they used it in the tutorial.

Alan Omar
  • 4,023
  • 1
  • 9
  • 20
  • 2
    What makes you think they used `Array.from` in the tutorial to get access to "all array methods" when (a) we don't know what tutorial that is and (b) the only method being used is `forEach` which you just said appears on NodeLists anyway! – Quentin Jun 07 '22 at 15:46
  • To be honest I have no idea what that tutorial might be, but it's more intuitive to use `Array.forEach` to loop, and the code is more extendable with array than it's with `NodeList`. – Alan Omar Jun 07 '22 at 16:14
-1

Not sure about the tutorial intention, but you can not call array functions on the NodeList object returned by querySelectorAll().

 document.querySelectorAll('.hw-text').map( ... ) // throws error
 [...document.querySelectorAll('.hw-text')].map( ... ) // works just fine
 Array.from(document.querySelectorAll('.hw-text')).map( ... ) // works just fine
Maik Lowrey
  • 15,957
  • 6
  • 40
  • 79
adiian
  • 1,382
  • 2
  • 15
  • 32
  • 1
    How is that relevant? They are using `forEach`, not `map`. – Quentin Jun 07 '22 at 15:47
  • 1
    It's relevant because the title of the question is quite clear: "Is there any advantage to using Array.from with a querySelectorAll()". That's definitely and advantage, regardless of the 2 equivalent expressions. – adiian Jun 07 '22 at 15:50
  • @adiian — Answers should take the whole question into consideration, not the brief summary in the title. – Quentin Jun 07 '22 at 15:54
  • 1
    @MaxPattern — Both arrays and node lists have a `forEach` method. – Quentin Jun 07 '22 at 15:55
  • @MaxPattern forEach is a method in both Array and NodeList, but in practice it happens often that you might need the methods of the Array, which makes sense to convert it. – adiian Jun 07 '22 at 15:59
  • @MaxPattern another reason to prefer other methods over forEach is because forEach behave strange in async contexts: https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop. In this case better to use `for (const element of arr)` – adiian Jun 07 '22 at 16:02