需要实现一个很简易的js模板.
现在有以下函数:
function compile(tpl, scope){
return tpl.replace(/\{\{([\s\S]+?)\}\}/g, function(caught, content){
var compiled;
try{
compiled = eval.call(scope, content);
}catch(e){
compiled = caught;
console.error(e);
}finally{
return compiled;
}
});
}
调用compile时
假设tpl为
<p> {{ uploadMaxSize / 1024 / 1024 }}M </p>
以及scope为
{ uploadMaxSize : 1048576 }
而运行结果如下
uploadMaxSize is not defined
这是为何
(另外, 请不要改变论点, 这边的问题是"如何指定一个object作为eval的上下文")
黄舟2017-04-10 14:37:10
于是...
function compile(tpl, scope){
return tpl.replace(/\{\{([\s\S]+?)\}\}/g, function(caught, content){
try{
return (new Function('with(this){return ' + content + '}')).call(scope);
}catch(e){
console.error(e);
return caught;
}
});
}
strict mode 也可以用with咯
PHP中文网2017-04-10 14:37:10
function compile(tpl, scope) {
tpl = tpl.replace(/\{%\s*(.*?)\s*%\}/g, function(_, k) {
for (var i in scope) {
this[i] = scope[i];
}
return eval(k);
});
return tpl.replace(/\{\{\s*(.*?)\s*\}\}/g, function(_, k) {
return scope[k];
});
}
应该这样写吧。
建议把模板填充和模板计算分开。分别用 {{}} 和 {%%}。
巴扎黑2017-04-10 14:37:10
直接写成:
compiled = scope[content];
不行吗?
还有你的模版是不是应该改成:
<p> {{ uploadMaxSize }}M </p>