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

时间:2012-12-07 16:38:46

标签: javascript undefined underscore.js

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

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

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

但是,Internet Explorer无法正常运行。而不是显示No description IE8和IE9显示[object HTMLMetaElement],而IE7显示[object]

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:5)

来自fine manual

  

默认情况下,模板会通过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属性。

答案 1 :(得分:0)

如果您typeof something且某些内容为null,则会返回object。检查'undefined'后尝试检查null。