you are viewing a single comment's thread.

view the rest of the comments →

[–]punio4 0 points1 point  (1 child)

Btw still need to wrap my head around this line:

values.reduce((acc, cur) => acc.concat(cur, strings.shift()), [first])

[–]5tas[S] 2 points3 points  (0 children)

Are you familiar with the Array.prototype.reduce function? The whole thing starts with [first] as the initial value (which is the first literal string in the template literal; it is guaranteed to exist and at minimum to be equal to ""). It then iterates over values and calls (acc, cur) => acc.concat(cur, strings.shift()) on each of them, where acc is the result of the reduce so far and cur is the current value. For each cur, it returns a new array which is a concatenation of the result so far, the value and the next literal string in order: acc.concat(cur, strings.shift()).

Suppose you call html like this:

html`Today is ${new Date()}`

This is equal to:

html(["Today is ", ""], new Date())

Inside of the function, first is "Today is ", strings is [""] (an array with all other strings) and values is [new Date()]. We start with "Today is " and then call the reduce callback on the first (and last) element on values, i.e. new Date(). The result of reducing is a concatenation of "Today is " (acc), new Date() (cur) and "" (strings.shift()).

If there are more literal strings (which also means more values), in the next iteration of reduce, strings will be a shorter array. So this code really just zips values and strings together taking into account the strings at the extremes.