【问题标题】:Javascript undefined conditionJavascript未定义条件
【发布时间】:2011-08-29 14:58:16
【问题描述】:

谁能给我解释一下if(obj.x == undefined)if(typeof obj.x == 'undefined')之间的区别

在某些情况下第一个工作正常,但在其他情况下我需要使用第二种方式。

问题

1 - 这两个条件有什么区别?

2 - 是否有最佳做法?

【问题讨论】:

  • 通常只检查值的真实性就足够了:if (obj.x)
  • undefined 是变量,不是常量,可以赋值。因此,一个学派认为第二条路径更安全,因为您无法确定undefined 的值。还有另一种观点认为,那些重新定义 undefined 的人应该得到他们所得到的。
  • 如果您想知道某个对象上是否存在属性,请执行此if ( 'x' in obj ) 或此if ( obj.hasOwnProperty( 'x' ) )。 (如果您不想查找原型链,请使用第二个。
  • @Chris Nielson - 从 1.8.5 开始,undefined 是不可写的

标签: javascript


【解决方案1】:

最佳实践是不仅要检查真实性,还要检查严格相等

例子

if (obj.x === undefined) {}

这是一个问题,因为undefined(全局属性)使用是可写的,从 1.8.5 开始是不可写的,为您提供 ES5 规范环境中的安全比较。

MDN

【讨论】:

  • 安全比较?在什么环境下? Afaik,您可以在所有现代浏览器中分配给 undefined 变量...
  • 还是不靠谱。即使在 ES5 中,undefined 也可以用作函数中的变量名:(function() { var undefined = "foo"; alert(undefined); })()
  • 那么为什么 MDN 会选择这个作为主要示例来查看变量是否为 undefined
  • @Šime:@jondavidjohn 关于全局 undefined 属性在当前浏览器中是只读的是正确的。
  • @jondavidjohn:MDN 并非万无一失。
【解决方案2】:

如果将相等运算符 == 替换为严格相等运算符 ===,则两者通常是等价的。所以obj.x === undefinedtypeof obj.x == "undefined" 通常是等价的。

但是,在 ECMAScript 5 之前的环境中(通常仍占大多数 Web 请求),undefined 是全局对象的可写属性,这意味着 undefined 可以用作变量名或可以为全局属性分配不同的值。 ECMAScript 5 将全局属性设为只读,但即便如此,undefined 仍可用作函数中的变量名,这意味着 typeof 检查总是更安全。

支持typeof 的另一点是,它可用于检查可能尚未声明的变量,而如果尚未声明变量,直接比较将抛出ReferenceError。例如:

typeof foo == "undefined" // true
foo === undefined // ReferenceError

但是,这是一件不寻常的事情,通常不会有帮助。

【讨论】:

  • undefined(全局变量)在哪些浏览器中不可写?
  • @Šime:试试看。我已经在 Firefox 6、Chrome 13、Safari 5.1 和 Opera 11.50 的机器上尝试过它。 Safari 和 Firefox 不允许分配给 undefined 全局对象属性,Chrome 和 Opera 允许。然而,这不是很相关:关键是兼容的 ES5 环境不允许这样做,而这样的环境确实存在。
  • 我的机器上刚好只有 Chrome 和 Opera :)
【解决方案3】:

由于 javascript 对特殊值的处理非常复杂,这两个测试不是等效的。在具体

undefined == null

是真的,但typeof undefined"undefined"typeof null"object"

这些特殊值的规则非常复杂且 IMO 不合逻辑,所以我认为没有“一般规则”。您可能会发现一些常见的形式,例如

var value = obj.x || default_value;

如果您确定 obj 永远不会是 undefinednull(因为在这种情况下会引发异常)并假设 0NaN 或空字符串应该被视为好像没有提供任何值(因为它们都是“逻辑错误”值)。一个空数组或一个空 javascript 对象被认为是“逻辑上正确的”。

为什么会这样?当null 根据typeof 显然是一个对象并且在对象中搜索不存在的字段通常返回undefined 时,为什么(null).x 会抛出异常?

我不知道。

我从未尝试在所有这些奇怪的规则中找到逻辑。实际上,我什至不能 100% 确定有一个。

我的建议只是研究和试验它们。

【讨论】:

  • 如果您不确定为什么会发生这种公认的不直观行为,请查看 ECMAScript 规范。您的观察直接遵循您可以在那里找到的明确定义的规则。
  • @Tim Down:我实际上已经尝试检查规格,但我个人发现该文档几乎无法阅读。我更喜欢尝试这些附带案例,因为无论如何,编写理论上应该运行但实际上却没有运行的程序不会有帮助(除非您的目标不是编写可以运行的软件,而是能够找到要责备的人)。
【解决方案4】:

第二个比第一个更容易和更快。首先需要额外的设置、未定义的定义并检查 obj 是否包含 x 作为属性或方法。其次检查是否 obj.x 已被定义和分配

PS.: undefined 将被评估为 null 所以 obj.x == undefined 等价于 obj.x == null

【讨论】:

    【解决方案5】:

    测试条件的最佳方法是使用 obj.x 这会检查 null-ability 和 undefined 。

    这样

    if(!obj.x) 
    {
      alert(obj.x);
    }
    else   
    {
      alert("obj.x is null or undefined");  //obj.x is null or undefined or any false value which is what you want. like obj.x is false or 0
    }
    

    【讨论】:

    • 这是不正确的。如果obj.x 是任何假值,而不仅仅是 null 或 undefined,则 else-branch 将被执行。
    【解决方案6】:

    这两个条件的主要区别是typeof

    typeof 运算符用于获取其操作数的数据类型(返回字符串)。操作数可以是文字或数据结构,例如变量、函数或对象。运算符返回数据类型。

    if (typeof obj.x === 'undefined') {
        txt = "x is undefined";
      } else {
        txt = "x is defined";
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多