使用Underscore.js检查未定义的变量

Ren*_*ené 2 javascript undefined underscore.js

我遇到了Underscore.js模板和Internet Explorer的问题.这是导致问题的模板的一部分:

<p>
  <% if ( typeof description !== 'undefined' ) { %>
    <%- description %>
  <% } else { %>
    No description
  <% } %>
</p>
Run Code Online (Sandbox Code Playgroud)

当变量description未定义时(这意味着我根本没有将它提供给模板,变量不存在),这在Safari,Firefox,Chrome中运行良好.

但是,Internet Explorer无法正常工作.而不是显示No descriptionIE8和IE9显示[object HTMLMetaElement],而IE7显示[object].

检查Safari,Firefox,Chrome中的typeof description返回结果undefined,但显然会返回Internet Explorer object.

我已经尝试过Underscore.js的_.isUndefined(value)函数,但是当变量不存在时,那个函数不起作用.

有谁知道这个问题的解决方法?(请注意,我无法提供没有值的变量 - 它存在,或者不存在)

更新我在其中一个Underscore.js Github问题中找到了一个解决方法https://github.com/documentcloud/underscore/issues/237#issuecomment-1781951

有人可以解释为什么IE表现不同,为什么解决方法实际上有效?

更新2 @ John-DavidDalton在下面的评论中提供了另一个更好的解决方法(直接链接到它似乎不起作用)

mu *_*ort 5

精细手册:

默认情况下,模板通过with语句将数据中的值放在本地作用域中.

您可以使用已编译模板的source属性查看正在发生的事情:

?var t = _.template('<%= v %>');
console.log(t.source);???????????????????
Run Code Online (Sandbox Code Playgroud)

给你(为了清晰调整):

function(obj) {
    var __t, __p = '';
    with(obj || {}) {
      __p += '' + ((__t = ( v )) == null ? '' : __t) + '';
    }
    return __p;
}
Run Code Online (Sandbox Code Playgroud)

with是你的问题的根源:

JavaScript通过搜索与包含该非限定名称的脚本或函数的执行上下文关联的作用域链来查找非限定名称.'with'语句在评估其语句体时将给定对象添加到此作用域链的头部.如果正文中使用的非限定名称与作用域链中的属性匹配,则该名称将绑定到属性和包含该属性的对象.否则抛出'ReferenceError'.

所以这个:

with(obj) {
    console.log(pancakes)
}
Run Code Online (Sandbox Code Playgroud)

JavaScript将首先查找obj.pancakes,如果没有pancakes属性obj,它将pancakes在全局范围内查找.显然,IE有一个window.description代表页面<meta>标签之一的值.在模板中使用您自己的命名空间(如在解决方法中)排除了什么with,并使您无法访问全局window属性.

  • 你可以通过传递一个`variable`选项来避免默认的with-statement:`_.template('<%= obj.v%>',null,{'variable':'obj'});`参见http:/ /underscorejs.org/#template (3认同)