我正在制作一个HTML模板引擎。
该程序将遍历HTML,并找到{{}}的所有实例。然后,它将遍历我们计数计数器中的所有键,并使用对控制器的引用替换变量名称的实例。
例如,如果我的控制器是{name:"grody"}
,而我的HTML具有{{name}}
,则我的程序将执行以下操作,将其替换为{{ctrl['name']}}
。
然后,程序将进行遍历,并将在所有表达式上使用eval()
对其求值。
所以像{{name + " joe"}}
-> {{ctrl['name'] + " joe"}}
-> grody joe
我得到的错误是ReferenceError,很明显在函数的eval
中发生。仅当存在多个变量时,才会发生ReferenceError,并且第一个变量将引发错误。
例如,如果模板是{{name}} is {{age}} years old}}
,它将在名称上获得ReferenceError。
但是,如果将名称命名为字符串,则控制器中的"na+me":"grody"
之类的内容将导致ReferenceError:未定义na。
这是代码:
function template(str, ctrl) {
var exp = str.match(/[^{{]+(?=\}})/g).map(function(x) {
return x.replace("}}", "")
})
for (var i = 0; i < exp.length; i++) {
for (var prop in ctrl) {
//console.log("propSearch:", prop.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'))
var evalExp = exp[i].replace(new RegExp(prop.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), "g"), "ctrl['" + prop + "']")
str = str.replace(new RegExp("{{" + exp[i].replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "}}", "g"), eval(evalExp))
//console.log(prop)
//console.log("exp[i]:", exp[i])
//console.log("evalExp:", evalExp)
//console.log("search:", exp[i].replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'))
//console.log("eval:", eval(evalExp))
//console.log("str", str)
evalExp = ""
}
}
return str
}
最佳答案
我认为您正在使事情变得复杂得多。我真的不明白为什么所有这些正则表达式和替换都是必需的。这是完成您要寻找的功能的函数:
const mustache = /\{\{(\w+)\}\}/g;
function template(str, ctrl) {
return str.replace(mustache, (match, key) => ctrl[key]);
};
这非常简单(它只能处理原始字符串键,而不能处理表达式),但是您可以处理传递给
.replace()
的回调,以使其更聪明。关于javascript - JavaScript ReferenceError被抛出到永不引用的变量上,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50488075/