在Node.js的ejs中如何检查未定义的属性?

49
什么是在ejs模板中检查未定义属性的最佳方法?
(我正在使用TJ Holowaychuk的node.js软件包
示例:
var tpl = '<% if (foo) { %>foo defined<% } else { %>foo undefined<% } %>';
console.log(ejs.render(tpl, { locals: { bar: "baz" } }));

我希望这将呈现为“foo undefined”。但实际上会抛出一个“foo undefined”错误。
我知道这不应该是个问题,因为这是在测试中预期的行为。有没有简单的方法可以避免这种情况?
我找到的唯一解决方案是使用hasOwnProperty方法。
var tpl = '<% if (hasOwnProperty("foo")) { %>foo defined<% } else { %>foo undefined<% } %>';
console.log(ejs.render(tpl, { locals: { bar: "baz"} }));

这不会引发任何错误。

有没有更好的方法来保持模板的清洁?或者为什么会引发这个错误?

4个回答

77

测试属性的另一种方法是通过 locals 对象间接引用它。使用你的示例:

var tpl = '<% if(locals.foo){ %>foo defined<% }else{ %>foo undefined<% } %>';
console.log(ejs.render(tpl, { locals: { bar: "baz"} }));

12
正好我需要这个,但是,靠,为什么你要这样做?! :) - Oscar Godson
我不确定,需要查看源代码,但我怀疑模板引擎对未定义的变量不会进行作用域限制。 - Richard Marr

33

我会使用typeof,例如if (typeof foo == 'undefined')。我使用字符串"undefined"和typeof运算符,而有些人可能会直接比较undefined全局变量。我喜欢这种方法,因为它可以防止一些恶意JavaScript库开发人员更改全局变量的值,从而使你的代码出错。

这也可以表示为一种三元表达式,有些人认为这样更简洁,因为没有花括号:

var tpl = '<% (typeof foo != "undefined" ? %>foo defined<% : %>foo undefined<% ) %>';

2
这个方法是可行的,也许它是正式正确的。但我个人不喜欢它,因为它对我的模板来说太长了。 - pvorb
1
请注意,这是唯一适用于客户端EJS模板的方法。其他方法依赖于检查“res”对象,而客户端模板中不存在该对象。 - dbasch

16

我认为最简单和最干净的方法是:

<%= (!!locals.foo)?foo:'' %>


3
似乎在更新的 EJS 版本中,本地变量已经转移到 res 对象中。 - dbasch
可以确认 <%= (locals.title) ? title : "默认标题" %> 是有效的。 - jpisty

3

早期版本的EJS仅支持locals,但现在最新版本的EJS支持res.locals

使用三元运算符的示例 -

<%= (res.locals.foo)?"foo":"" %>

if-else 的示例代码 -

<% if (res.locals.urvariable) { %>
   <h1><%= urvariable.value1 %></h1> 
<% } else { %> 
   <h1><%= urvariable.value2 %></h1> 
<% } %>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接