我正在制作一个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/

10-12 14:03