There is such code:

function func(name, str) { var newStr = '`' + str + '`'; return newStr; } var firstName = 'Mark'; var str = 'hi ${name}'; var f = func.bind(null, firstName); console.log(f(str)); 

Conclusion now:

hi $ {name}

How to:

hi mark

How to pass template strings in functions correctly?

  • you need to use ` (where the letter is e), not ' ........ var str = `hi ${name}`; ....... although in your case you are trying to do something completely strange - Alexey Shimansky
  • In this case, I get that the variable name is not defined. The point is to use a string pattern in a function. - MarkL7
  • @Regent is not, he is not about that ... but what he wants is most likely impossible to do. in any case, without crookedness - Alexey Shimansky
  • @Regent I understand that, but I need something else. Pass the name and pattern to the function. And already in the function to use this name in the template. Is it possible at all? - MarkL7
  • @ Alexey Shimansky, to transfer the "template" to a function, in order to call it in it for the transferred value ... - Regent

4 answers 4

This is normally impossible to do.

It will not correctly transfer the template, but the function that fills this template:

 function hiTo(name) { return `Hi ${name}`; } var firstName = 'Mark'; var f = hiTo.bind(null, firstName); console.log(f()); 

If this is an attempt to localize, then you can substitute the values ​​yourself, and not use the template lines:

 function hiTo(args, template) { return template.replace(/\$\{(\w+)\}/g, (m,n) => args[n] || m); } var firstName = 'Mark'; var f = hiTo.bind(null, {name: firstName}); console.log(f('Hi ${name}')); console.log(f('Привет ${name}')); 

    The easiest way is to pass a function instead of a string:

     var strf = name => `Hi, ${name}!`; func("Mark", strf); function func(name, strf) { console.log(strf(name)); } 

    In more complex cases, you will need new Function (but make sure that untrusted strings do not get there!):

     var str = 'Hi, ${name}!'; var strf = compile(str); func("Mark", strf); function func(name, strf) { console.log(strf(name)); } function compile(str) { return new Function("name", "return `" + str + "`"); } 

    Even if the names of the variables are unknown in advance, you will have to use the obsolete construction with :

     var str = 'Hi, ${name}!'; var strf = compile(str); func({ name: "Mark" }, strf); function func(data, strf) { console.log(strf(data)); } function compile(str) { return new Function("$data", "with ($data) return `" + str + "`"); } 

    But it is better not to bring it up to this and dwell on the first variant.

    • new Function(...keys, looks better than with and works in strict mode. - Qwertiy
    • @Qwertiy what is such a strict mode inside new Function ? :-) - Pavel Mayorov
    • @Qwertiy what to ...keys - then note that I share the compilation of the template and its use. With this approach, this very list of keys will have to be compiled manually, which will complicate things even more. - Pavel Mayorov
    • Hmm .. Yes, indeed, the place is not that ... - Qwertiy

    In a simple way, like in your question, you cannot do this (or I don't know how). It is necessary to fence various designs or crutches. Example:

     var template = function(tpl, args) { var keys = Object.keys(args), fn = new Function(...keys, 'return `' + tpl.replace(/`/g, '\\`') + '`'); return fn(...keys.map(x => args[x])); }; function test() { var myTpl = 'Hello ${str + "!"} and ${other.toUpperCase()}'; console.log(template(myTpl, {str: 'foo', other: 'bar'})); } test(); 

    Taken from https://stackoverflow.com/a/41118285/6104996


    But as for me, it's easier for templates in this case to use a trite replace on a regular schedule.

    • Thanks for the answer! - MarkL7
    • " template(myTpl, name=firstName) " - global variables? Something I don’t understand at all, why this answer is better than eval ... - Qwertiy
    • And also does not work on tpl = 'hi \\${name}' - Qwertiy
    • @Qwertiy is precisely why I think this is all wrong, even though it’s very poorly working. As I wrote - it is better to make a cutout on the regular regular basis + to have an agreement on the correct design of patterns - Alexey Shimansky
    • @ MarkL7 Do not rush to tick off the answer. maybe someone else would recommend. for all this is not so simple. In general, a practical advice is to use ready-made template engines IMHO)) or the correct regular schedule for the template previously specified in the standard - Alexey Shimansky

    You can use eval

     function func(name, str) { var a = '`'+str+'`'; var newStr = eval(a); return newStr; } var firstName = 'Mark'; var str = 'hi ${name}'; var f = func.bind(null, firstName); console.log(f(str)); 

    But as it turned out, not necessary. First, not safe. Secondly, this option does not work with backslashes in the template. They are not escaped. The template still breaks in eval.

    • And why is the code from this answer bad? - tilin
    • Thanks for the answer. The solution looks pretty simple. Why minusanuli this decision is also interesting. Suppose that due to the security issue of using eval. - MarkL7
    • @ MarkL7, firstly, security, secondly, does not work, for example, on str = 'hi \\${name}' . Although the minus is not mine. - Qwertiy
    • Try eval('`'+JSON.stringify(s)+'`') - I don’t understand, it will be better, or vice versa in other cases it will break ... - Qwertiy