skip to Main Content

According to MDN,

String.raw() is the only built-in template literal tag. It has close semantics to an untagged literal since it concatenates all arguments and returns a string. You can even re-implement it with normal JavaScript code.

How would you "re-implement String.raw() with normal JavaScript code"? If I write my own template literal function const raw = (s, v) => ..., the string array s contains strings that are no longer raw. For example,

raw `anb`

will pass a-newline-b, whereas the raw string would be a-backslash-n-b.

My raw() template literal function could reverse the quoting by turning newline into backslash-n, but that’s not reliable. How does it distinguish between:

raw `anb`

and

raw `a
b`

?

2

Answers


  1. The array that is passed as first argument to the template tag function has an additional property raw, as documented here. It contains the same as strings itself but as raw strings, without parsing escape sequences.

    This means that String.raw could be replicated as follows:

    function myRaw (strings, ...values) {
      return strings.raw.reduce((result, s, i) => result + s + (values[i] ?? ''), '')
    }
    

    Note that if we’d replace strings.raw.reduce with just strings.reduce, we’d get a "do-nothing" template tag function.

    Login or Signup to reply.
  2. For this to work properly, you have to make use of the raw property of the first argument to the template function. It contains an array of the raw contents of the string as it exists in the source code, without backslash being treated as an escape character.

    For example:

    function raw(strings, ...values) {
      const output = [];
     
      for (let i = 0; i < strings.length; i++) {
        output.push(strings.raw[i]);  // <== instead of strings[i]
        if (i < values.length) {
          output.push(values[i]);
        }
      }
      
      return output.join("");
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search