使用Underscore.js检查未定义的变量 [英] checking for undefined variable with Underscore.js

查看:55
本文介绍了使用Underscore.js检查未定义的变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用Underscore.js模板和Internet Explorer时遇到问题.这是引起麻烦的模板的一部分:

I'm having a problem with Underscore.js templates and Internet Explorer. Here's part of the template which is causing trouble:

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

当未定义变量 description 时(这意味着我根本不将其提供给模板,该变量不存在),这在Safari,Firefox,Chrome中正常运行.

When the variable description is undefined (which means I'm not supplying it to the template at all, the variable does not exist), this works just fine in Safari, Firefox, Chrome.

Internet Explorer不能正常工作.IE8和IE9不会显示 No description ,而不会显示 [object HTMLMetaElement] ,而IE7则显示 [object] .

Internet Explorer however, doesn't work correctly. Instead of showing No description IE8 and IE9 show [object HTMLMetaElement], and IE7 shows [object].

检查描述类型的结果会在Safari,Firefox,Chrome中返回 undefined ,但显然Internet Explorer会返回 object .

Checking the result of typeof description returns undefined in Safari, Firefox, Chrome, but apparently Internet Explorer returns object instead.

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

I already tried Underscore.js's _.isUndefined(value) function, but that one doesn't work when the variable does not exist.

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

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

Update I found a workaround in one of the Underscore.js Github issues https://github.com/documentcloud/underscore/issues/237#issuecomment-1781951

有人可以解释为什么IE行为不同,为什么变通办法实际上有效吗?

Can someone explain why IE behaves differently, and why the workaround actually works?

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

Update 2 @John-DavidDalton has provided another, better workaround in the comments below (linking directly to it doesn't seem to work)

推荐答案

摘录自精细手册:

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

By default, template places the values from your data in the local scope via the with statement.

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

You can see what's going on using the compiled template's source property:

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

为您(为清楚起见进行了调整):

gives you (tweaked for clarity):

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

with 是您问题的根源:

The with is the source of your problem:

JavaScript通过搜索与包含该不合格名称的脚本或函数的执行上下文相关联的作用域链来查找不合格名称."with"语句在评估其语句主体时将给定对象添加到此作用域链的头部.如果主体中使用的非限定名称与作用域链中的某个属性匹配,则该名称将绑定到该属性以及包含该属性的对象.否则会引发"ReferenceError".

JavaScript looks up an unqualified name by searching a scope chain associated with the execution context of the script or function containing that unqualified name. The 'with' statement adds the given object to the head of this scope chain during the evaluation of its statement body. If an unqualified name used in the body matches a property in the scope chain, then the name is bound to the property and the object containing the property. Otherwise a 'ReferenceError' is thrown.

因此,此:

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

JavaScript首先会查找 obj.pancakes ,如果 obj 中没有 pancakes 属性,它将查找 pancakes在全局范围内.显然,IE具有一个 window.description 值,该值表示页面的< meta> 标记之一.在模板中使用您自己的名称空间(如在变通方法中一样)会否定 with 的作用,并使您无法访问全局的 window 属性.

JavaScript will first look for obj.pancakes and if there is no pancakes property in obj, it will look for pancakes in the global scope. Apparently IE has a window.description value which represents one of the page's <meta> tags. Using your own namespace inside the template (as in the work-around) sort of negates what with does and keeps you from getting to the global window properties.

这篇关于使用Underscore.js检查未定义的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆