【问题标题】:JavaScript: undefined !== undefined?JavaScript:未定义!==未定义?
【发布时间】:2010-10-21 02:07:33
【问题描述】:

注意:根据ECMAScript5.1, section 15.1.1.3,window.undefined 是只读的。

  • 现代浏览器正确地实现了这一点。例如:Safari 5.1、Firefox 7、Chrome 20 等。
  • Undefined 在 Chrome 14 中仍然可以更改,...

当我最近将Facebook ConnectTersus 集成时,我最初在尝试调用Facebook API 函数时收到了错误消息Invalid Enumeration ValueHandler already exists

原来问题的原因是

object.x === undefined

当 'object' 中没有属性 'x' 时返回 false。

我通过在两个 Facebook 函数中用常规相等替换严格相等来解决这个问题:

FB.Sys.isUndefined = function(o) { return o == undefined;};
FB.Sys.containsKey = function(d, key) { return d[key] != undefined;};

这对我来说是可行的,但似乎暗示 Facebook 的 JavaScript 代码和我自己的代码之间存在某种冲突。

这是什么原因造成的?

提示:有据可查的是undefined == nullundefined !== null。这不是这里的问题。问题是我们怎么会得到undefined !== undefined

【问题讨论】:

  • 有趣,我刚刚在我的控制台中尝试过。 var a = {}; a.b === undefined //true。您确定您的 object.x === undefined 返回 false 是因为对象中没有字段 x 吗?
  • " 根据 ECMAScript5.1 第 15.1.1.3 节,window.undefined 是只读的。" - 霍雷,因为在以前的版本中,有人可以全局覆盖undefined,一切都会中断:(
  • window.undefined 是只读的之前,void(0) 被认为是标准的额外安全方法,如果你不想相信你是环境的@ 987654337@ 变量。 MDN

标签: javascript


【解决方案1】:

A)。我从来没有也永远不会相信任何声称在没有用户编码的情况下生成代码的工具,它是图形工具的两倍。

B)。我在使用 Facebook Connect 时从未遇到过任何问题。无论您身在何处,它仍然是在浏览器和 undefined===undefined 中运行的普通 JavaScript 代码。

简而言之,您需要提供证据证明您的 object.x 确实是未定义的,而不是 null 或其他,因为我相信您所描述的情况实际上是不可能的 - 没有冒犯:) - 我会为 Tersus 代码中存在的问题投入资金。

【讨论】:

  • 谢谢,安娜卡塔。您持怀疑态度的回答让我重新审视了这个问题并找到了正确的答案(见下文)。
【解决方案2】:

我想发布一些关于undefined的重要信息,初学者可能不知道。

看下面的代码:

 /* 
  * Consider there is no code above. 
  * The browser runs these lines only.
  */

   // var a;  
   // --- commented out to point that we've forgotten to declare `a` variable 

   if ( a === undefined ) {
       alert('Not defined');
   } else {
       alert('Defined: ' + a);
   }

   alert('Doing important job below');

如果您运行此代码,其中变量 a 从未使用 var 声明过, 您将收到一个 ERROR EXCEPTION 并且令人惊讶地根本看不到任何警报。

您的脚本不会“在下面做重要的工作”,而是会意外终止,在第一行抛出未处理的异常。


这是使用 typeof 关键字检查 undefined 的唯一防弹方法,它就是为此目的而设计的:

   /* 
    * Correct and safe way of checking for `undefined`: 
    */

   if ( typeof a === 'undefined' ) {
       alert(
           'The variable is not declared in this scope, \n' +
           'or you are pointing to unexisting property, \n' +
           'or no value has been set yet to the variable, \n' + 
           'or the value set was `undefined`. \n' +
           '(two last cases are equivalent, don\'t worry if it blows out your mind.'
           );
   }

   /* 
    *  Use `typeof` for checking things like that
    */

此方法适用于所有可能的情况。

使用它的最后一个参数是undefined 可能会在早期版本的 Javascript 中被覆盖:

     /* @ Trollface @ */
        undefined = 2;
     /* Happy debuging! */  

希望我已经足够清楚了。

【讨论】:

  • function xx(a) { if(a === undefined)a='default'; } xx() - 这是在 javascript 中安排默认参数的好方法
【解决方案3】:

来自 - JQuery_Core_Style_Guidelines

  • 全局变量:
    typeof variable === "undefined"

  • 局部变量:
    variable === undefined

  • 属性:
    object.prop === undefined

【讨论】:

  • 请注意——如果一个变量根本不存在,那么它既不是局部的也不是全局的。不太直观的是,我们应该像检查全局变量一样检查那些可能不存在的变量,正如 Dan 在他的示例中向我们展示的那样。
【解决方案4】:
var a;

typeof a === 'undefined'; // true
a === undefined; // true
typeof a === typeof undefined; // true
typeof a === typeof sdfuwehflj; // true

【讨论】:

    【解决方案5】:

    使用== 相等运算符而不是=== 是一种不好的做法。

    undefined === undefined // true
    null == undefined // true
    null === undefined // false
    

    如果x 是未知属性,则object.x === undefined 应返回true

    在第 Bad Parts of JavaScript: The Good Parts 章中,Crockford 写道:

    如果您尝试从 一个对象,如果该对象没有 有一个同名的成员,它 而是返回未定义的值。

    除了未定义,JavaScript 有一个类似的值,称为 null。他们 如此相似以至于 == 认为它们是 平等的。这让一些程序员感到困惑 认为他们是 可互换,导致代码类似

    value = myObject[name];
    if (value == null) {
        alert(name + ' not found.');
    }
    

    它正在将错误的值与 错误的运营商。此代码有效 因为它包含两个错误 互相抵消。那是一个疯子 编程方式。写得更好 像这样:

    value = myObject[name];
    if (value === undefined) {
        alert(name + ' not found.');
    }
    

    【讨论】:

    • 你读过这篇精彩的文章吗:webreflection.blogspot.ie/2010/10/…
    • (value == null) 通常是一个非常理智和有效的比较。您实际上想要多久区分未定义的内容和明确为空的内容? 为什么没有价值并不重要。
    【解决方案6】:

    事实证明,您可以将 window.undefined 设置为您想要的任何值,因此当 object.x 是 real 未定义时得到object.x !== undefined。就我而言,我无意中将 undefined 设置为 null。

    看到这种情况发生的最简单方法是:

    window.undefined = null;
    alert(window.xyzw === undefined); // shows false
    

    当然,这不太可能发生。在我的例子中,这个错误有点微妙,相当于下面的场景。

    var n = window.someName; // someName expected to be set but is actually undefined
    window[n]=null; // I thought I was clearing the old value but was actually changing window.undefined to null
    alert(window.xyzw === undefined); // shows false
    

    【讨论】:

    • 啊哈!而 this 是我反对使用 undefined 属性(而不是使用 typeof)的主要原因。恭喜你解决了这个错误。 +1
    • 总是为对象命名的另一个原因... var n = blah.someName;废话[n]=空;会让你永远不会得到那个错误......
    • 现代浏览器无法覆盖它
    【解决方案7】:

    问题是 undefined 与 null 相比使用 == 给出了 true。 因此,对 undefined 的常见检查是这样完成的:

    typeof x == "undefined"
    

    这确保了变量的类型确实是未定义的。

    【讨论】:

    • 这里的许多答案中最大的误解是“未定义”是 Javascript 关键字。它根本不是关键字,而是(大多数情况下)碰巧未定义的变量。所以“somevar === undefined”唯一有效的时候是“undefined”变量真正没有被定义的时候。我见过代码(jcanvas),其中类包装函数包含一个名为“undefined”的最后一个参数(从未使用过),只是为了确保在函数范围内会有一个名为“undefined”的未定义变量。除了这种特殊情况,使用 'typeof' 是唯一“正确”的方式。
    • 这是否意味着,只要它永远不会被定义,我也可以使用 garglblarg 代替 undefined?
    • @Dercsár:是的,var foo; foo === undefined // true
    • 其实不是这样的。 undefined 不是关键字,而是 JavaScript 内置的。引用实际上未定义的内容会引发ReferenceError: whatever is not defined
    • 有人能解释一下为什么 myVar === undefined 会引发 ReferenceError,而 this.myVar === undefined 不会(只返回 true)吗? P.S. myVar 从未被定义过。