【问题标题】:JavaScript templating engine - Converting left hand ternary (without an assignment) into conditional statement(s)JavaScript 模板引擎 - 将左手三进制(无赋值)转换为条件语句
【发布时间】:2016-03-28 20:27:03
【问题描述】:

我找到了由 Krasimir 构建的 完美 JavaScript 模板引擎,它正是我所需要的。
模板引擎工作得很好,但我自然无法抗拒对它进行修改的冲动,甚至可能添加一些功能。
不幸的是,我无法理解某些代码。

代码如下:

var TemplateEngine = function(html, options) {
  var re = /<%([^%>]+)?%>/g,
    reExp = /(^( )?(if|for|else|switch|case|break|{|}))(.*)?/g,
    code = 'var r=[];\n',
    cursor = 0,
    match;
  var add = function(line, js) {
    /* --begin problem  */
    js ? (code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n') : (code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : '');
    /* --end problem    */
    return add;
  };
  while (match = re.exec(html)) {
    add(html.slice(cursor, match.index))(match[1], true);
    cursor = match.index + match[0].length;
  }
  add(html.substr(cursor, html.length - cursor));
  code += 'return r.join("");';
  return new Function(code.replace(/[\r\t\n]/g, '')).apply(options);
};

这是我不明白的行:

js ? (code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n') : (code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : '');

我对 JavaScript 并不陌生,但那是一些看起来很奇怪的代码,据我所知,它是一个没有左手赋值的三元运算符(如果我错了,请纠正我)

因此,为了更好地理解作者在做什么,我尝试将三元运算符转换为条件语句。

这是我目前所拥有的:

if(js) {
  if(code += line.match(reExp)) {
    line += '\n';
  } else {
    line += 'r.push(' + line + ');\n';
  }
} else {
  if(code += line !== '') {
    line += 'r.push("' + line.replace(/"/g, '\\"') + '");\n';
  } else {
    line += "";
  }
}

这失败并抛出错误“Uncaught SyntaxError: Unexpected token if”

谁能帮我把这段代码转换成条件语句,甚至可以解释一下这段代码的作用?

出于好奇,谁能告诉我 IE8 是否支持此代码?
注意:我不介意 IE8 支持我只想知道这个模板引擎是否支持 IE8。

您可以在 Krasimir 的 Website 或 Krasimir 的 Github 上找到模板引擎

【问题讨论】:

  • 您的备用代码没有语法错误。如果您收到该错误,则它来自其他地方。
  • @Pointy 是的,这就是我的想法,我也 100% 肯定模板代码也没有语法错误,因为我使用了示例中的相同代码,也许我已经声明中有错误?

标签: javascript templates templating client-side-templating templating-engine


【解决方案1】:

您不应该将代码附加到必须附加到代码的行,试试这个:

if (js && type(js) !== "undefined") {
  if (line.match(reExp)) {
    code += line;
  } else {
    code += "r.push(" + line + ");";
  }
} else if (line !== "") {
  code = code + "r.push(\"" + line.replace(/"/g, '\\"') + "\");";
}

【讨论】:

    【解决方案2】:

    三元运算符?: 在 JavaScript 中的工作方式与在 C 中一样。在这种情况下,我们可以将表达式格式化为

    js? (code += (line.match(reExp)? line + '\n' : 'r.push(' + line + ');\n')
      : (code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : '');
    

    它看起来就像一个 if-else 块。整个表达式计算为两个复合赋值表达式之一,具体取决于js 的值。这个表达式的值被忽略了,但我们仍然可以从中得到副作用。作者只是选择写这个而不是if (js) { code += ...; } else { code += ...; }

    【讨论】:

    • Evelyn,看来原始答案的海报已被禁止,所以我接受了你的答案,代表必须去找人:) 再次非常感谢你的回答,干杯。
    【解决方案3】:

    我知道这个问题并没有引起太多关注,但我想无论如何我都会发布这个答案,希望它能帮助面临这个问题的人。
    在 JSHint 的一些努力和 ton 的帮助下,我找到了问题的解决方案。
    我将当前编译的行附加到“行”变量而不是“代码”变量。
    这导致“line”变量包含模板的最后一行和编译代码的其余部分,这意味着“code”变量没有代码 :D,因此等同于 null .

    这是我在弄清楚我做错了什么之前的代码:

    var add = function(line, js) {
      if(js) {
        if(code += line.match(reExp)) {
          line += '\n';
        } else {
          line += 'r.push(' + line + ');\n';
        }
      } else {
        if(code += line !== '') {
          line += 'r.push("' + line.replace(/"/g, '\\"') + '");\n';
        } else {
          line += "";
        }
      }
    };
    

    在这里和那里用“code”变量替换“line”变量并在此处进行一些优化后,这是最终的工作答案:

    var add = function(line, js) {
      if(js && typeof js !== "undefined") {
        if(line.match(reExp)) {
          code += line;
        } else {
          code += "r.push(" + line + ");";
        }
      } else if(line !== "") {
        code += "r.push(\"" + line.replace(/"/g, '\\"') + "\");";
      }
    };
    

    【讨论】:

      猜你喜欢
      • 2014-01-18
      • 1970-01-01
      • 2012-02-12
      • 1970-01-01
      • 2010-12-18
      • 2012-07-16
      • 2019-05-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多