是否可以创建一个模板字符串作为一个普通的字符串,

let a = "b:${b}";

然后把它转换成一个模板字符串,

let b = 10;
console.log(a.template()); // b:10

没有eval, new Function和其他动态代码生成的手段?


当前回答

不,如果没有动态代码生成,就没有办法做到这一点。

然而,我已经创建了一个函数,它将把一个常规字符串转换为一个函数,可以提供一个值的映射,在内部使用模板字符串。

生成模板字符串

/**
 * Produces a function which uses template strings to do simple interpolation from objects.
 * 
 * Usage:
 *    var makeMeKing = generateTemplateString('${name} is now the king of ${country}!');
 * 
 *    console.log(makeMeKing({ name: 'Bryan', country: 'Scotland'}));
 *    // Logs 'Bryan is now the king of Scotland!'
 */
var generateTemplateString = (function(){
    var cache = {};

    function generateTemplate(template){
        var fn = cache[template];

        if (!fn){
            // Replace ${expressions} (etc) with ${map.expressions}.

            var sanitized = template
                .replace(/\$\{([\s]*[^;\s\{]+[\s]*)\}/g, function(_, match){
                    return `\$\{map.${match.trim()}\}`;
                    })
                // Afterwards, replace anything that's not ${map.expressions}' (etc) with a blank string.
                .replace(/(\$\{(?!map\.)[^}]+\})/g, '');

            fn = Function('map', `return \`${sanitized}\``);
        }

        return fn;
    }

    return generateTemplate;
})();

用法:

var kingMaker = generateTemplateString('${name} is king!');

console.log(kingMaker({name: 'Bryan'}));
// Logs 'Bryan is king!' to the console.

希望这能帮助到一些人。如果你发现代码有问题,请及时更新Gist。

其他回答

@Mateusz Moska,解决方案很好,但当我在React Native(构建模式)中使用它时,它抛出一个错误:无效字符'”,尽管当我在调试模式下运行它时它是有效的。

所以我用正则表达式写出了我自己的解。

String.prototype.interpolate = function(params) {
  let template = this
  for (let key in params) {
    template = template.replace(new RegExp('\\$\\{' + key + '\\}', 'g'), params[key])
  }
  return template
}

const template = 'Example text: ${text}',
  result = template.interpolate({
    text: 'Foo Boo'
  })

console.log(result)

演示:https://es6console.com/j31pqx1p/

注:因为我不知道问题的根本原因,我在react-native repo中提出了一张票,https://github.com/facebook/react-native/issues/14107,这样一旦他们能够修复/指导我大致相同:)

您可以参考这个解决方案 Const interpolate = (str) => new Function(' return \ ' ${new String(str)}\ '; ')(); const foo = 'My'; Const obj = { 文本:汉尼拔·莱克特 firstNum: 1、 secondNum: 2 } Const STR = "${foo}名称为:${obj.text}。Sum = ${obj。firstNum} + ${obj。secondNum} = ${obj。firstNum + obj.secondNum}"; console.log(插入(str));

由于模板字符串必须动态地(在运行时)获得对b变量的引用,所以答案是:不,没有动态代码生成是不可能做到的。

但是,使用eval非常简单:

let tpl = eval('`'+a+'`');

我知道我来晚了,但你可以:

Const a = (b) => ' b:${b} '; 令b = 10; console.log (a (b));/ / b: 10

在我的项目中,我用ES6创建了这样的东西:

String.prototype.interpolate =函数(参数){ const names = Object.keys(params); const vals = Object.values(params); 返回新功能(…的名字,‘返回’$ { }\`;`)(... 瓦尔斯); } const template = '示例文本:${text}'; Const result = template.interpolate({ 文本:“Foo Boo” }); console.log(结果);