【问题标题】:Difference between undefined and not being defined in JavascriptJavascript中未定义和未定义之间的区别
【发布时间】:2011-03-26 02:32:50
【问题描述】:

请参阅http://jsfiddle.net/FDhQF/1/ 了解一个简单的示例。

在 Javascript 中未定义的东西和未定义的东西有什么区别?例如,尝试访问未定义对象的属性(实际上是尝试访问变量)将返回undefined。但是你也可以设置一些= undefined。当您这样做时,尝试访问它仍然返回未定义,但指针仍然存在。如上所述,一个示例是对对象的迭代仍然会遍历您已(重新)声明为未定义的属性。似乎有两种不同的未定义。任何人都可以了解情况吗?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    访问未在对象上定义的属性和包含原始undefined 值的属性都会返回undefined。

    例如:

    var obj = {
      a: undefined
    };
    
    obj.a; // undefined
    obj.b; // undefined
    

    区别在于a 是自己的属性,而b 不是:

    obj.hasOwnProperty('a'); // true
    obj.hasOwnProperty('b'); // false
    

    在第一种情况下,a 是一个自己的属性,即使它包含 undefined 作为其值。在第二种情况下,b 不是自己的属性,访问 obj.b 将在原型链中查找名为 b 的属性。

    当原型链结束时(当它到达带有null[[Prototype]] 的对象时),属性查找结束并显式返回undefined。

    您应该知道hasOwnProperty 方法仅检查属性是否物理存在于对象上(拥有属性),但我们也有继承属性,为此case我们可以使用in operator,例如:

    function Test () {}
    Test.prototype.a = 'foo'; // instances of Test will inherit from Test.prototype
    
    var obj = new Test(); // { a="foo",  b="bar"}
    obj.b = 'bar';
    
    obj.hasOwnProperty('a');  // false
    'a' in obj;               // true
    obj.a;                    // 'foo'
    
    obj.hasOwnProperty('b');  // true
    

    如您所见,obj 继承自 Test.prototype,a 属性不是自己的属性,但它可以通过原型链获得。这就是为什么hasOwnProperty 返回false 而in 运算符返回true。

    你可以看到[[Get]]内部操作是如何解析内部属性的

    注意事项:

    • 访问 undefined 作为标识符在 ECMAScript 3(最广泛实施的语言标准版本)上被认为是不安全的,因为不是作为语言关键字(例如 null)只是一个全局对象的属性,并且在这个版本的规范上是可写的,这意味着如果有人替换它的值(例如window.undefined = 'LOL';),它会破坏你的代码。

    @strager 提到的typeof operator 可以代替使用,例如:

    if (typeof obj.prop == 'undefined') { /*....*/ }
    

    此运算符总是返回一个字符串(使用== 是安全的:),其值取决于其操作数的类型,可能的值描述为here。

    解决此问题的另一种常见方法是声明您自己的 undefined 变量,该变量在您的函数范围内可用,例如,某些库使用以下模式:

    (function(undefined) {
      // code here
    })();
    

    该函数有一个名为 undefined 的参数,它会立即执行而不向其传递任何值(最后一对或括号进行调用)。

    也许值得一提的是,undefined global property 最终在 ECMAScript 5 中被描述为不可写(不可变,以及不可枚举和不可配置-不可删除-)。

    • 直接从对象实例中使用hasOwnProperty 方法也不被认为是安全,因为如果某个对象具有同名的属性,则原始方法将被遮蔽。例如:

      var obj = { hasOwnProperty: function () { /* evil code :) */ } };
      

    如果你打电话:

        obj.hasOwnProperty('prop'); 
    

    对象上定义的方法将被执行(你不会想要这个,因为你确切知道要调用哪个方法...),因为它遮蔽来自@的方法987654365@,但是可以通过以下方式安全地调用它:

        Object.prototype.hasOwnProperty.call(obj, 'prop');
    

    【讨论】:

    • 除了.hasOwnProperty,还有in 操作符,我认为需要提及。
    • 在您的第一个注释中:指定要检查值是否未定义,请使用typeof x === 'undefined'。另外,我不明白为什么Object.prototype.hasOwnProperty 会被认为是不安全的;我将它用于您声称它不安全的相同目的。你能澄清一下吗?
    • @CMS,啊,我误会了。感谢您的澄清。
    • 感谢您的详细回答,CMS。在这一点上,我仍然看不到 Javascript 的 undefined 实现优于似乎更传统的“抛出/引发异常”或“返回 nil/null”方法的优势,但你的答案肯定有助于阐明情况..
    • @Steven Xu,我自己希望在访问未定义的属性时抛出异常,但又一次阻止了像 x = foo.bar || default; 这样的简单速记,我只是 love 在 JavaScript .
    【解决方案2】:

    Here 很好地解释了“未定义”。然而,要点是,将某些内容设置为“未定义”并不是 UN 定义它,因为“未定义”实际上是一个原始值,当变量(或属性)没有被赋值时使用。

    【讨论】:

    • undefined 实际上是最初设置为原始值的变量。例如,当从没有显式返回值的函数返回时,使用原始值,而不是变量。
    • 另外,您提供的链接似乎没有直接回答问题。
    猜你喜欢
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 2011-07-03
    • 1970-01-01
    • 2012-07-28
    • 2016-09-02
    • 2010-10-21
    相关资源
    最近更新 更多