Your example under "heavy nesting" is a poster child for everything WRONG with "functions for nothing" as not only are you adding the overhead of function calls inside the loop, you're spreading the code out all over creation to... make it "easier" to follow?!? That's not simpler or easier, it's just code bloat for... well, uhm... Christmas only knows what.

I'm seeing this attitude a lot of late with people saying that things which are more cryptic (like the derpy "arrow functions"), unneccessary (const/let), wasteful (endless pointless functions for nothing), etc, etc are all somehow magically easier, or simpler, or better when -- to me at least -- they are the OPPOSITE of those things. I've been doing this stuff for well over four decades, I've never seen such utter bull being promoted as good practice! The really sad part of idiocy like let/const being that we already have a perfectly good and more powerful mechanism, the IIFE that makes them utterly pointless in 99% of use cases.

Is this a side effect of the twitter generation, where anything more than ten lines of code in a row triggers that same "Wah wah, wall of text" reaction so common to the TLDR mouth-breathers?

Even when it's the same amount of code -- which miraculously your two examples are 572 bytes exactly for each -- spreading it out all over creation is NOT providing "clarity", and again with the overhead of function calls and "take objects down and pass it around" it's not particularly performant either. Particularly when laden with the variables for nothing. More so with the pointless overhead of object.keys added to the mix, in a structure where you could just be appending as you go instead of post-append. (since there are no INPUT and you're not IE compatible anyways!)

... and really if one were to split out things into a function paying said overhead, wouldn't using a function for the ONE thing you do over and over again -- create and append -- pay off higher dividends in both code clarity and simplicity?

That you also seem to be saving up all your DOM additions for nothing doesn't help. Despite all the whackjob claims of "batch your DOM additions" that only applies if all your additions don't happen in the same execution thread... something that the majority of time in JavaScript isn't even a thing unless you're dealing with timeouts and events! (and even then)

BIG tip? appendChild and insertBefore both return the element that was appended. Leverage that.

Really though these types of nonsensical "complaints" about code clarity, with the idiotic "teh funzion es two lung" and equally derpy "but muh blok scoops" seeming to be entirely rooted in people who refuse to maintain consistent formatting, refuse to leverage whitespace for clarity, and cannot even handle the most basic of logic structures.

I'd take this:

(function(d) {  function make(tagName, parent, content) {
var e = parent.appendChild(d.createElement(tagName));
if (content) e.textContent = content;
return e;
}
var
items = {
foo: [1, 2, 3],
bar: [1, 2, 3],
baz: [1, 2, 3]
},
ul = make('ul', d.body);

for (var item in items) {

var
ul_li_ul = make('ul', make('li', ul, item)),
values = items[item];

for (
var i = 0, iLen = values.length;
i < iLen;
i++
) make('li', ul_li_ul, values[i]);

} // for items

})(document);

... over either of what you presented there. If you're going to introduce a function to the overhead of this, don't do it TO the loop you only are likely to need/use in that exact form once. Instead make it for the longer more verbose operation you are doing all the time... though if performance were a concern I'd cut out the function and just do it thus:

(function(d) {  var
items = {
foo: [1, 2, 3],
bar: [1, 2, 3],
baz: [1, 2, 3]
},
ul = d.body.appendChild(d.createElement('ul'));
for (var item in items) { var
ul_li = ul.appendChild(d.createElement('li')),
ul_li_ul = ul_li.appendChild(d.createElement('ul')),
values = items[item];
ul_li.insertBefore(d.createTextNode(item), ul_li_ul); for (
var i = 0, iLen = values.length;
i < iLen;
i++
) (
ul_li_ul.appendChild(d.createElement('li'))
).textContent = values[i];
} // for items})(document);

Which if you pull the excess blank lines and the comment, is smaller than your originals even with the wrapping IIFE... and of course this far clearer code works all the way back to IE 5. But tell me again how all this let/const/arrow/for+of+Object.keys garbage is "better"

I don't know what's in this flavor aid these new language features are peddling, but it sure seems to promote delusional behavior.

Also notice that if you have a variable that's just used like the length in a loop, you can declare it on the loop's var/let/const using comma delimits. You don't need to place it outside the loop. AGAIN as I've been telling JS developers for near on two decades, STOP saying "var" for each and every joe-blasted variable when you can comma delimit and provide clearer formatting!

Hence:

for (var i = 0, iLen = arr.length; i < iLen; i++) {

Is all you need... and don't forget that if you know all iterable entries are loose true -- such as in a nodeList -- you can loop by assignment:

for (var i = 0, value; value = iterable[i]; i++) {

In the majority of cases executes many times faster than a conventional (i < length) loop, and BOTH of them actually execute faster than for/of, and ALL of them execute faster than Array.forEach since we don't have the overhead of a function callback interfering.

Side note, can anyone explain to me why you’d for/of Object.keys instead of for/in? I can’t find a definitive answer on why you’d ever even consider or need to do that in the first place… Both only work on enumerables so what’s the difference apart from the newer one being more code and executing slower?

You also went full Gungan on the subject of the DOM. Proper DOM manipulation is plenty fast, certainly faster than many of the alternatives… but where you really went off the rails was saying that static stuff belongs in the markup… whilst mostly true for content, if an element ONLY works when JavaScript is enabled/present it has ZERO business in the markup and should be built on the DOM.

Shame most people seem to think that DOM manipulation means getElementsBy/QuerySelector and innerHTML/textContent, and couldn’t walk the DOM even if she was threatening them with a whip.

Proper DOM manipulation is one of the fastest ways to put dynamic content into a page. Element.appendChild, Element.insertBefore, document.createElement, document.createTextNode… you’re going straight to the DOM tree and leveraging its pointer-based structure, bypassing the parser entirely. Just as Node.parentNode, Node.nextSibling, Node.previousSibnling and the Element counterparts let you bypass the slow getElement(s)By / querySelector crap in a lot of cases.

But what can one expect when most people don’t even know how to use Event properly, much less the difference between Event.target and Event.currentTarget… and instead do constant get/query BS bloating out their code in both size and performance.

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store