我遇到了Underscore.js模板和Internet Explorer的问题。这是导致问题的模板的一部分:
<p>
<% if ( typeof description !== 'undefined' ) { %>
<%- description %>
<% } else { %>
No description
<% } %>
</p>
当变量description
未定义时(这意味着我根本没有将它提供给模板,变量不存在),这在Safari,Firefox,Chrome中运行良好。
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在下面的评论中提供了另一个更好的解决方法(直接链接到它似乎不起作用)
答案 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。