是否可以创建一个模板字符串作为一个普通的字符串,
let a = "b:${b}";
然后把它转换成一个模板字符串,
let b = 10;
console.log(a.template()); // b:10
没有eval, new Function和其他动态代码生成的手段?
是否可以创建一个模板字符串作为一个普通的字符串,
let a = "b:${b}";
然后把它转换成一个模板字符串,
let b = 10;
console.log(a.template()); // b:10
没有eval, new Function和其他动态代码生成的手段?
当前回答
我制定了自己的解决方案,用描述作为函数来处理类型
export class Foo {
...
description?: Object;
...
}
let myFoo:Foo = {
...
description: (a,b) => `Welcome ${a}, glad to see you like the ${b} section`.
...
}
这样做:
let myDescription = myFoo.description('Bar', 'bar');
其他回答
由于模板字符串必须动态地(在运行时)获得对b变量的引用,所以答案是:不,没有动态代码生成是不可能做到的。
但是,使用eval非常简单:
let tpl = eval('`'+a+'`');
不,如果没有动态代码生成,就没有办法做到这一点。
然而,我已经创建了一个函数,它将把一个常规字符串转换为一个函数,可以提供一个值的映射,在内部使用模板字符串。
生成模板字符串
/**
* 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。
在我的项目中,我用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(结果);
这里的问题是有一个函数可以访问它的调用者的变量。这就是为什么我们看到直接eval被用于模板处理。一种可能的解决方案是生成一个函数,接受由字典属性命名的形式参数,并以相同的顺序使用相应的值调用它。另一种方法是这样简单:
var name = "John Smith";
var message = "Hello, my name is ${name}";
console.log(new Function('return `' + message + '`;')());
对于任何使用Babel编译器的人,我们需要创建一个闭包,它可以记住创建它的环境:
console.log(new Function('name', 'return `' + message + '`;')(name));
我知道我来晚了,但你可以:
Const a = (b) => ' b:${b} '; 令b = 10; console.log (a (b));/ / b: 10