【问题标题】:JavaScript - Identify whether a property is defined and set to 'undefined', or undefinedJavaScript - 确定属性是否已定义并设置为“未定义”或未定义
【发布时间】:2010-09-28 00:13:24
【问题描述】:

假设我有以下代码:

function One() {}
One.prototype.x = undefined;

function Two() {}

var o = new One();
var t = new Two();

o.xt.x 都将评估为 undefinedo.hasOwnProperty('x')t.hasOwnProperty('x') 都将返回 false; propertyIsEnumerable 也是如此。两个问题:

  • 有什么方法可以判断 o.x 已定义并设置为undefined
  • 有任何理由吗? (两者在语义上应该是等价的吗?)

一个小警告:执行 (for propName in o) 循环将产生 'x' 作为字符串之一,而在 t 中执行不会 - 因此它们在内部的表示方式存在差异(至少在铬)。

【问题讨论】:

    标签: javascript object properties undefined


    【解决方案1】:

    您可以尝试在 One.x 上放置一个手表,但这只会在它未定义时告诉您。

    【讨论】:

    • 不,他用原始值'undefined'定义它。
    • 取消定义将使用“删除”。
    【解决方案2】:

    Ach,其中一个用于反模式线程。

    undefined 不是关键字。

    当您分配写入var foo = undefined; 时,您将分配给它您尚未定义的符号undefined 的值,因此您将获得的值是"undefined"。如果您将其分配给 UnDeFiNeDNotFineAtAll_qwertyuiop,您将产生完全相同的结果

    为什么这么可怕?好吧,除了它会导致对正在发生的事情产生错误的理解之外,如果你碰巧加载了一个库或雇佣了一个编写 var undefined = true; 的开发人员会发生什么@

    【讨论】:

    • 啊,很有趣。但是,请注意 - 将其设置为“UnDeFiNed”将导致编译时错误,因为该变量未定义。将其设置为“Object.randomStringinserthereplease”按照您所说的方式进行。
    • 你的意思是运行时,没有用 JS 编译这样的东西——但你是对的,我的描述假设范围。问题的出现是因为 undefined 在很多情况下都可以被视为一个常量,并且已经被一些浏览器支持,但是它不是一个常量并且不安全
    • 如果你想知道某些东西是否未定义而不管有人改变了 undefined 的值:typeof x === "undefined"
    • @annakata: undefined 是一个原始值,参见 ECMAScript 规范的第 4.3.9 节。当你说“你正在为它分配你尚未定义的符号 undefined 的值”时,你错了(续)
    • @annakata:但是,你是对的,它不是一个常量,如果 undefined 被定义为其他东西,它会产生意想不到的行为。这也是:eval=function(){alert("eval 不再支持");}
    【解决方案3】:

    object.hasOwnProperty(name) 仅对同一对象中的对象返回 true,对其他所有对象(包括原型中的属性)返回 false。

    function x() {
      this.another=undefined;
    };
    
    x.prototype.something=1;
    x.prototype.nothing=undefined;
    y = new x;
    
    y.hasOwnProperty("something"); //false
    y.hasOwnProperty("nothing"); //false
    y.hasOwnProperty("another"); //true
    
    "someting" in y; //true
    "another" in y; //true
    

    此外,删除属性的唯一方法是使用删除。将其设置为 undefined 不要删除它。

    正确的做法是像roborg所说的那样使用in

    更新: undefined 是一个原始值,请参阅ECMAScript Language Specification 第 4.3.2 和 4.3.9 节。

    【讨论】:

      【解决方案4】:

      没有。我不认为等于 undefined 的变量应该被识别为“已定义”。

      直接将其设置为等于undefined 只是一种删除它的懒惰方式——与使用delete 关键字相反。我相信这只是意味着垃圾收集没有对变量/属性产生影响。


      [编辑]

      关于您对hasOwnPropertypropertyIsEnumerable 的评论,原型方法/属性既不是对象自己的,也不是可枚举的。

      Object.prototype.foo = 'something';
      
      var o = {bar: 'anything'};
      o.hasOwnProperty('foo');  //=> false
      o.hasOwnProperty('bar');  //=> true
      
      Object.prototype.hasOwnProperty('foo');  //=> true
      

      【讨论】:

      • 将其设置为原始值 undefined 不会删除该属性,但您会失去对该属性包含的任何内容的引用。与垃圾回收未生效无关。
      【解决方案5】:

      比你的方法更简单的方法是使用Javascript in operator

      alert('x' in o); // true
      alert('x' in t); // false
      

      【讨论】:

      • in 关键字在 ECMAScript 标准中吗?它在 Gecko 和 Webkit 中实现,但我不知道是否可以始终依赖它的存在。
      • @kpozin 您可以安全地使用in。看到这个问题:stackoverflow.com/questions/2920765/…
      【解决方案6】:

      这样的?

      function isDefined(var){
         return (typeof(window[var]) == 'undefined') ? false : true;
      }
      

      或者..

      function isDefined(var){
         return (window.var === undefined) ? false : true;
      }
      

      【讨论】:

      • 我认为这两种变体的作用相同
      【解决方案7】:

      一种方法是这样的:

      var definedProperties = [];
      for (var prop in o) definedProperties.push(prop);
      
      if (o.x === undefined && contains(prop, 'x')) {
          //x is defined, but set to undefined
      }
      

      其中contains 只是检查数组中是否有任何元素是'x'。这是唯一的方法吗?

      【讨论】:

      • “包含”?那不是 ECMAScript。即使是这样,您的解决方案也会放慢速度并使用比需要更多的资源。像其他答案中所说的那样使用“x in y”。
      • 我知道,我忘了 ECMAScript 有一个“in”运算符 =P。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-25
      • 1970-01-01
      • 1970-01-01
      • 2011-11-20
      • 1970-01-01
      相关资源
      最近更新 更多