Justifying forEach (which is several times slower than a for loop) with sparse arrays (which are an anti-pattern because they take you out of "fast elements" mode in V8 at least) is laughable in a sad way. It also has no "break" functionality , which is important if we are talking about performance (i.e. when iterating the array to find a specific member).
The advice for using array literals to insert elements is also bad for the similar reason that it makes it easy to create sparse arrays.
That and "i>arr.length" in the example means the for loop will run exactly 0 times! ;)
Using "filter", "map" and "reduce", by the way, is also slower than using a for loop, even if broken out into a separate function for purposes of chaining. This is because they call a function on each iteration and function calls (even with optimisation) are inherently more expensive. So, use them only when this difference in performance does not matter.
The closure / timer example is just so convoluted. Of course the closure will keep "bar" in scope - that's what closures do! The "foo" object doesn't somehow magically own "bar" it just has a reference to it, same as the closure. If something still references an object then GC will not touch it.
Similarly for the event listeners advice, which is also badly worded.
And if you do need to write a timeout-based loop, I respectfully suggest the following construct:
const interval = 1000;
var timer;
(function loop () {
... do stuff ...
timer = setTimeout(loop, interval);
}());
Now you can even use "rewire" to control the interval during your unit tests - bonus!The Arrays vs Objects thing is just shallow. In reality, the advice is "it depends". If you need to iterate, use an Array. If you need to access by key, use an Object (or better a Map). If you need both (and this frequently happens in my experience) then you have to decide depending on the size of your structure.