1

I am looking for a way to use a Template String from a variable in function.

This is a working example (not a variable)

let f = function () {
  return `Hello ${this.name}!`
}
f.bind({
  name: 'Stackoverflow-User'
})(); // Hello Stackoverflow-User!

This is the not working example (in a variable)

let s = `Hello ${this.name}!`;
let f = function () {
  return s;
}
f.bind({
  name: 'Stackoverflow-User'
})(); // Hello undefined!
TJR
  • 6,307
  • 10
  • 38
  • 64
  • 1
    Umm, why not just do `let f = s` in your final solution??? – Bergi Feb 19 '16 at 00:15
  • Oh no .. now I am confused ... I've worked in my solution with a fix value instead of a variable. I will update my solution ... – TJR Feb 19 '16 at 00:18
  • @FelixKling: That's a horrible duplicate imo – Bergi Feb 19 '16 at 00:24
  • @Bergi: Yeah, I noticed that after I read it completely. Do you have a better one? Didn't you answer such a question? – Felix Kling Feb 19 '16 at 00:24
  • @FelixKling: [the two I linked from there](http://stackoverflow.com/questions/30003353/can-es6-template-literals-be-substituted-at-runtime-or-reused#comment48130107_30003353) are pretty canonical, but not sure whether they're a duplicate of this here. – Bergi Feb 19 '16 at 00:26
  • @Bergi: http://stackoverflow.com/q/22607806/1048572 fits IMO. At least it's the same problem. Unfortunately this question doesn't really contain a question. – Felix Kling Feb 19 '16 at 00:27

1 Answers1

2

This:

let f = function () {
  return `Hello ${this.name}!`
}

gets compiled into this:

let f = function () {
  return "Hello " + this.name.toString() + "!";
}

and it will work as soon as f is called as a method of proper object. Expression gets evaluated each time you call the function.

And in your second case:

var s = "Hello " + this.name.toString() + "!";

let f = function () {
  return s;
}

that s gets its value only once - at load time and with wrong this.

The only way to make it work that way is to generate function from it:

let s = new Function("return `Hello ${this.name}!`;");

and use it as:

let f = function () {
  return s.call(this);
}

A bit weird but will work.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
c-smile
  • 26,734
  • 7
  • 59
  • 86
  • Because "this" was manipulated I changed it a bit but inspired by your solution. See my update above! Thanks. – TJR Feb 18 '16 at 23:06
  • 1
    `return s.bind(this)();` is just a waste of memory and CPU. You create another function object. Just do `return s.call(this);` instead. – c-smile Feb 18 '16 at 23:10
  • You really shouldn't use the `eval` solution. – Bergi Feb 18 '16 at 23:38