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

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 = cache[template] = Function('map', `return \`${sanitized}\``);
            }

            return fn;
        };

        return generateTemplate;
    })();

其他回答

例如,您可以使用字符串原型

String.prototype.toTemplate=function(){
    return eval('`'+this+'`');
}
//...
var a="b:${b}";
var b=10;
console.log(a.toTemplate());//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(结果);

这个解决方案不需要ES6:

function render(template, opts) {
  return new Function(
    'return new Function (' + Object.keys(opts).reduce((args, arg) => args += '\'' + arg + '\',', '') + '\'return `' + template.replace(/(^|[^\\])'/g, '$1\\\'') + '`;\'' +
    ').apply(null, ' + JSON.stringify(Object.keys(opts).reduce((vals, key) => vals.push(opts[key]) && vals, [])) + ');'
  )();
}

render("hello ${ name }", {name:'mo'}); // "hello mo"

注意:Function构造函数总是在全局作用域中创建,这可能会导致全局变量被模板覆盖,例如render("hello ${someGlobalVar = 'some new value'}", {name:'mo'});

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

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

您可以参考这个解决方案 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));