Javascript if(输入对象)或if(对象.hasOwnProperty(键)

Javascript if(输入对象)或if(对象.hasOwnProperty(键),javascript,Javascript,以下两个语句是否产生相同的输出?是否有任何理由选择一种方式而不是另一种方式 if (key in object) if (object.hasOwnProperty(key)) 中的也将检查继承的属性,而hasOwnProperty中的情况并非如此。第一个版本较短(尤其是在重命名变量的小型代码中) vs 无论如何,正如@AndreMeinhold所说,它们并不总是产生相同的结果。小心——它们不会产生相同的结果 如果在原型链的某个地方找到key,则in也将返回true,而Object.ha

以下两个语句是否产生相同的输出?是否有任何理由选择一种方式而不是另一种方式

 if (key in object)

 if (object.hasOwnProperty(key))

中的
也将检查继承的属性,而
hasOwnProperty中的情况并非如此。第一个版本较短(尤其是在重命名变量的小型代码中)

vs


无论如何,正如@AndreMeinhold所说,它们并不总是产生相同的结果。

小心——它们不会产生相同的结果

如果在原型链的某个地方找到
key
,则
in
也将返回
true
,而
Object.hasOwnProperty
(正如名称已经告诉我们的那样)将只返回
true
,前提是
key
直接在该对象上可用(其“拥有”该属性)

另一种形式(在中调用)枚举属性名(或键) 在每次迭代中,从 对象被分配给变量。通常需要进行测试 hasOwnProperty(变量),以确定属性名称 是对象的真正成员,或者是在原型链上找到的。


(来自Crockford的Javascript:好的部分)

我将尝试用另一个例子来解释。 假设我们有以下具有两个属性的对象:

function TestObj(){
    this.name = 'Dragon';
}
TestObj.prototype.gender = 'male';
让我们创建TestObj的实例:

var o = new TestObj();
让我们检查对象实例:

console.log(o.hasOwnProperty('name')); // true
console.log('name' in o); // true

console.log(o.hasOwnProperty('gender')); // false
console.log('gender' in o); // true
结论:

  • 如果对象可以直接或从原型访问属性,in运算符将始终返回true

  • hasOwnProperty()仅当实例上存在属性而其原型上不存在属性时才返回true

如果我们想检查原型上是否存在某些属性,逻辑上,我们会说:

console.log(('name' in o) && !o.hasOwnProperty('name')); //false
console.log(('gender' in o) && !o.hasOwnProperty('gender')); //true - it's in prototype
最后:

所以,关于这两个条件

if (key in object)
if (object.hasOwnProperty(key))
…产生相同的结果,答案是显而易见的,这取决于。

总之,
hasOwnProperty()
不会在原型中查找,而
中的
会在原型中查找

摘自:

您可以确定对象是否具有具有 通过使用hasOwnProperty()方法并传入 成员的名称。以确定对象是否有权访问 属性,则可以使用in运算符。例如:

在这段代码中,当传入“title”时,hasOwnProperty()返回true 因为title是一个对象实例;当 传入“toString”,因为它在实例上不存在 每个属性名称都与in运算符一起使用,结果为true 这两次都是因为它搜索实例和原型


你得到了一些非常好的答案。 我只想提供一些东西,让您不用在迭代对象时检查“hasOwnProperty”

创建对象时,通常人们会以以下方式创建:

const someMap = {}
// equivalent to: Object.create(Object.prototype)
// someMap.constructor will yield -> function Object() { [native code] }
const key
for(key in someMap ){
 if (someMap.hasOwnProperty(key)) { 
   // Do something
 }
}
现在,如果您想通过“someMap”进行迭代,您必须这样做:

const someMap = {}
// equivalent to: Object.create(Object.prototype)
// someMap.constructor will yield -> function Object() { [native code] }
const key
for(key in someMap ){
 if (someMap.hasOwnProperty(key)) { 
   // Do something
 }
}
我们这样做是为了避免对继承属性进行迭代

如果您打算创建一个仅用作“映射”(即键值对)的简单对象,您可以这样做:

const newMap = Object.create(null);
// Now, newMap won't have prototype at all.
// newMap.constructor will yield -> undefined
因此,现在可以安全地进行如下迭代:

for(key in cleanMap){
 console.log(key + " -> " + newMap [key]);
 // No need to add extra checks, as the object will always be clean
}

我学到了这个很棒的技巧

如果在原型链的某个地方找到key,那么你对中的
到底意味着什么也会返回true。你能写一个例子吗?谢谢。@Lor:
({foo:bar})。hasOwnProperty(“toString”)
vs
({foo:bar})中的“toString”
in
运算符与in
语句中的
不同。实际上,这两个运算符都是in关键字的不同用法是的,
in
是一个关键字。但是OP询问的是作为
in
运算符的
的具体用法。您的答案涉及到作为in
语句的
的一部分的其他用法。您可能已经知道了最好将此作为评论。:-)更详细的评论:
const newMap = Object.create(null);
// Now, newMap won't have prototype at all.
// newMap.constructor will yield -> undefined
for(key in cleanMap){
 console.log(key + " -> " + newMap [key]);
 // No need to add extra checks, as the object will always be clean
}