typeof foo [' bar']!==' undefined'与' bar'在foo

时间:2011-03-25 15:13:16

标签: javascript

这两个表达式的返回值之间有什么区别......

表达式1:typeof foo['bar'] !== 'undefined'

表达式2:'bar' in foo

...假设满足这些条件:

  1. foo是一个对象,
  2. foo不包含任何明确设置值undefined的属性。

6 个答案:

答案 0 :(得分:5)

第一个测试barfoo的值。

第二次测试bar中是否存在foo属性。

var foo = {bar:undefined};

typeof foo['bar'] !== 'undefined'; // false

'bar' in foo;  // true

修改

要从下面的评论中添加一些说明,OP的问题是访问domConfig的{​​{1}}属性会引发错误。

这是与window.document运算符无关的问题,而是与Firefox的特定问题有关。

问题has been documented here是一个错误(早在2003年)。

该报告中的一些值得注意的评论:

  

Zbigniew Braniecki [:gandalf] 2003-11-19 09:09:31太平洋标准时间

     

那为什么可以用for-in迭代它?

     

Boris Zbarsky(:bz)2003-11-19 09:24:05 PST

     

因为 被定义为nsIDOM3Document接口上的属性。它的   如果你试图访问其吸气剂,只会抛出一个。 ...

     

Zbigniew Braniecki [:gandalf] 2003-11-19 09:33:53太平洋标准时间

     

......那是什么类型的错误?

     

目标是从接口或删除未实现的方法/属性   实施它?!?

     

鲍里斯·扎巴斯基(:bz)2003-11-19 09:53:23太平洋标准时间

     

目标是最终实现这一目标。

答案 1 :(得分:2)

我对规范的解读表明它们应该是一样的。 “in”运算符语义是根据对内部(概念)[[HasProperty]]方法的调用来定义的,该方法本身是根据[[GetProperty]]定义的。当[[HasProperty]]返回“undefined”时,“in”运算符会产生布尔值false;否则它是true。基于[[GetProperty]]应该做什么的定义,这意味着属性访问的“未定义”结果具有相同的含义。

答案 2 :(得分:1)

var foo = {};
foo.bar = undefined;

console.log("bar" in foo); // true
console.log(typeof foo["bar"] !== "undefined"); // false

var Con = function() {};
Con.prototype.bar = undefined;
var foo = new Con;

console.log("bar" in foo); // true
console.log(typeof foo["bar"] !== "undefined"); // false

in检查与使用for in循环完全相同,如果keyfor in循环中,则返回true。

[编辑]没有看到你的“不明确将其设置为undefined”条件。

var foo = {}
Object.defineProperty(foo, "bar", { 
    "value": 42,
    "enumerable": false

});

console.log("bar" in foo); // true (in chrome & FF4)
console.log(typeof foo["bar"] !== 'undefined'); // true

如果您将in测试设置为不可枚举,我会非常期望var foo = {} Object.defineProperty(foo, "bar", { "value": 42, "writable": false }); console.log("bar" in foo); // true (in chrome & FF4) console.log(typeof foo["bar"] !== 'undefined'); // true 测试失败。好像它们是一样的。

var foz = {}
Object.defineProperty(foz, "bar", { 
    "value": 42
});
var foo = Object.freeze(foz);

console.log("bar" in foo); // true (in chrome & FF4)
console.log(typeof foo["bar"] !== 'undefined'); // true

如果属性是“只读”,则两个测试仍然有效

{{1}}

冻结对象也不会破坏测试。

答案 3 :(得分:1)

鉴于你提出的条件,没有区别。两者都应该产生相同的布尔结果,并且应该在原型查找周围表现相同。

Object.prototype.hasOwnProperty.call(null, foo, 'bar')

是另一种常见的习惯用法,与这两种用法相同,但不包含仅在原型上可用的属性。

答案 4 :(得分:1)

鉴于这两个条件,表达式应该给出相同的结果,除非

  • foobar属性定义了一个EcmaScript 5 getter。由于第一个表达式实际上读取了属性值,因此将调用该getter。第二个表达式只检查属性的存在,因此不需要任何这样的getter。
  • 您的目标是Internet Explorer 4.0 - 在JavaScript 1.4之前未添加in运算符;)

这里有一些sample code来说明支持浏览器(Chrome,IE9,FF4)的区别:

var foo = {};
Object.defineProperty(foo, "bar", { 
    "get": function () {document.write("Getter invoked!<br/>"); return foo;}
});

document.write('"bar" in foo -->' + 
               ("bar" in foo));
document.write('<br/>');
document.write('typeof foo["bar"] !== "undefined" -->' +
               (typeof foo["bar"] !== "undefined"));
document.write('<br/>');

答案 5 :(得分:0)

第一个首先检查foo中是否存在'bar'键(如果未找到则返回undefined),然后检查该键的类型。 第二个只检查存在。