2

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

<p>
  <% if ( typeof description !== 'undefined' ) { %>
    <%- description %>
  <% } else { %>
    No description
  <% } %>
</p>

当变量description未定义时(这意味着我根本没有将它提供给模板,变量不存在),这在 Safari、Firefox、Chrome 中工作得很好。

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

检查 Safari、Firefox、Chrome 中的typeof description返回结果undefined,但显然 Internet Explorerobject会返回。

我已经尝试过 Underscore.js 的_.isUndefined(value)功能,但是当变量不存在时,该功能不起作用。

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

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

有人可以解释为什么 IE 的行为不同,以及为什么解决方法实际上有效吗?

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

4

2 回答 2

5

来自精美手册

默认情况下,模板with通过语句将数据中的值放在本地范围内。

source您可以使用已编译模板的属性查看发生了什么:

​var t = _.template('<%= v %>');
console.log(t.source);​​​​​​​​​​​​​​​​​​​

为您提供(为清晰起见进行了调整):

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

with是您的问题的根源:

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

所以鉴于此:

with(obj) {
    console.log(pancakes)
}

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

于 2012-12-07T17:35:35.577 回答
0

如果您typeof something和某事是nullobject则返回。检查 null 后尝试检查'undefined'.

于 2012-12-07T17:00:14.653 回答