从未引用的变量抛出JavaScript ReferenceError

时间:2018-05-23 12:10:38

标签: javascript templates referenceerror

我正在制作HTML模板引擎。

程序浏览HTML,找到{{}}的所有实例。然后它遍历我们的countroller中的所有键,并用对控制器的引用替换变量名的实例。

例如,如果我的控制器为{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
}

1 个答案:

答案 0 :(得分:1)

我认为你让它变得比它需要的复杂得多。我真的不明白为什么所有这些正则表达式和替换都是必要的。这是一个能够完成您正在寻找的内容的功能:

const mustache = /\{\{(\w+)\}\}/g;

function template(str, ctrl) {
    return str.replace(mustache, (match, key) => ctrl[key]);
};

它非常简陋(它只能处理原始字符串键,但不能处理表达式),但您可以处理传递给.replace()的回调以使其更智能。