是否可以创建一个模板字符串作为一个普通的字符串,
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和其他动态代码生成的手段?
当前回答
我知道我来晚了,但你可以:
Const a = (b) => ' b:${b} '; 令b = 10; console.log (a (b));/ / b: 10
其他回答
这个解决方案不需要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'});
这样做(这样做):
让a = 'b:${this.b}' 令b = 10 函数template(templateString, templateVars) { 返回new函数('return " + templateString + ' ").call(templateVars) } 结果。textContent = template(a, {b}) < b id =结果> < / b >
有很多好的解决方案张贴在这里,但没有一个利用ES6字符串。原始的方法。这是我的贡献。它有一个重要的限制,它只接受传入对象的属性,这意味着模板中的代码执行将不起作用。
function parseStringTemplate(str, obj) {
let parts = str.split(/\$\{(?!\d)[\wæøåÆØÅ]*\}/);
let args = str.match(/[^{\}]+(?=})/g) || [];
let parameters = args.map(argument => obj[argument] || (obj[argument] === undefined ? "" : obj[argument]));
return String.raw({ raw: parts }, ...parameters);
}
let template = "Hello, ${name}! Are you ${age} years old?";
let values = { name: "John Doe", age: 18 };
parseStringTemplate(template, values);
// output: Hello, John Doe! Are you 18 years old?
将字符串拆分为非参数的文本部分。看到正则表达式。 部分:[“你好,”,“!”你多大了?”) 将字符串拆分为属性名。如果匹配失败则为空数组。 参数:["name", "age"] 通过属性名映射obj中的参数。解决方案受限于浅的一级映射。未定义的值用空字符串代替,但接受其他假值。 参数:["John Doe", 18] 使用String.raw(…)并返回结果。
你想要的是:
//从问题中引用的非工作代码 让b = 10; console.log (a.template ()); / / b: 10
与eval完全相同(就功能和安全而言):获取包含代码的字符串并执行该代码的能力;执行的代码还可以看到调用者环境中的局部变量。
在JS中,函数无法看到调用者中的局部变量,除非该函数是eval()。甚至Function()也做不到。
当您听说JavaScript中出现了所谓的“模板字符串”时,很自然地认为这是一个内置的模板库,就像Mustache一样。它不是。它主要是字符串插值和JS的多行字符串。不过,我认为这在一段时间内将是一个普遍的误解。:(
这里的问题是有一个函数可以访问它的调用者的变量。这就是为什么我们看到直接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));