Javascript if (key in object) or if(object.hasOwnProperty(key)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13632999/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 12:32:25  来源:igfitidea点击:

if (key in object) or if(object.hasOwnProperty(key)

javascript

提问by Lorraine Bernard

Do the following two statements produce the same output? Is there any reason to prefer one way to the other?

以下两个语句是否产生相同的输出?有什么理由更喜欢一种方式吗?

 if (key in object)

 if (object.hasOwnProperty(key))

回答by Andre Meinhold

Be careful - they won't produce the same result.

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

inwill also return trueif keygets found somewhere in the prototype chain, whereas Object.hasOwnProperty(like the name already tells us), will only return trueif keyis available on that object directly (its "owns" the property).

in也将返回true如果key得到的地方找到原型链,而Object.hasOwnProperty(好像是这个名字已经告诉我们),将只返回true,如果key是可用的对象直接(其“拥有”的属性)。

回答by Dalibor

I'l try to explain with another example. Say we have the following object with two properties:

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

function TestObj(){
    this.name = 'Dragon';
}
TestObj.prototype.gender = 'male';

Let's create instance of TestObj:

让我们创建 TestObj 的实例:

var o = new TestObj();

Let's examine the object instance:

让我们检查对象实例:

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

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

Conclusion:

结论:

  • in operator returns true always, if property is accessible by the object, directly or from the prototype

  • hasOwnProperty() returns true only if property exists on the instance, but not on its prototype

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

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

If we want to check that some property exist on the prototype, logically, we would say:

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

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

Finally:

最后:

So, regarding to statement that these two conditions ...

所以,关于声明这两个条件......

if (key in object)
if (object.hasOwnProperty(key))

...produce the same result, the answer is obvious, it depends.

...产生相同的结果,答案很明显,这取决于。

回答by xavier.seignard

inwill also check for inherited properties, which is not the case for hasOwnProperty.

in还将检查继承的属性,而hasOwnProperty.

回答by Etienne No?l

In summary, hasOwnProperty()does not look in the prototype while indoes look in the prototype.

综上所述,hasOwnProperty()不看原型而in确实看原型。

Taken from O'Reilly High Performance Javascript:

摘自O'Reilly 高性能 Javascript

You can determine whether an object has an instance member with a given name by using the hasOwnProperty() method and passing in the name of the member. To determine whether an object has access to a property with a given name, you can use the in operator. For example:

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

var book = {
    title: "High Performance JavaScript",
    publisher: "Yahoo! Press" 
};

alert(book.hasOwnProperty("title"));  //true
alert(book.hasOwnProperty("toString"));  //false
alert("title" in book); //true 
alert("toString" in book); //true

In this code, hasOwnProperty() returns true when “title” is passed in because title is an object instance; the method returns false when “toString” is passed in because it doesn't exist on the instance. When each property name is used with the in operator, the result is true both times because it searches the instance and prototype.

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

回答by asafel

You got some really great answers. I just want to offer something that will save you the need for checking "hasOwnProperty" while iterating an object.

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

When creating an object usually people will create it in this way:

创建对象时,通常人们会以这种方式创建它:

const someMap = {}
// equivalent to: Object.create(Object.prototype)
// someMap.constructor will yield -> function Object() { [native code] }

Now, if you want to iterate through "someMap" you will have to do it this way:

现在,如果你想遍历“someMap”,你必须这样做:

const key
for(key in someMap ){
 if (someMap.hasOwnProperty(key)) { 
   // Do something
 }
}

We are doing so in order to avoid iterating over inherited properties.

我们这样做是为了避免迭代继承的属性。

If you intend to create a simple object that will only be used as a "map" (i.e. key - value pairs) you can do so like that:

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

const newMap = Object.create(null);
// Now, newMap won't have prototype at all.
// newMap.constructor will yield -> undefined

So now it will be safe to iterate like this:

所以现在像这样迭代是安全的:

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

I learned this awesome tip here

在这里学到了这个很棒的技巧

回答by Jahan

The other form (called for in) enumerates the property names (or keys) of an object. On each iteration, another property name string from the object is assigned to the variable. It is usually necessary to test object.hasOwnProperty(variable) to determine whether the property name is truly a member of the object or was found instead on the prototype chain.

另一种形式(在 in 中调用)枚举对象的属性名称(或键)。在每次迭代中,来自对象的另一个属性名称字符串被分配给变量。通常需要测试 object.hasOwnProperty(variable) 来确定属性名称是真正属于对象的成员还是在原型链上找到的。

 for (myvar in obj) {
     if (obj.hasOwnProperty(myvar)) { ... } }

(from Crockford's Javascript: The Good Parts)

(来自 Crockford 的Javascript: The Good Parts

回答by antonjs

The first version is shorter (especially in minified code where the variables are renamed)

第一个版本较短(特别是在变量重命名的缩小代码中)

a in b

vs

对比

b.hasOwnProperty(a)

Anyway, as @AndreMeinhold said, they do not always produce the same result.

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