if(key in object)或者if(object. hasownproperty (key)

下面两个语句产生相同的输出吗?我们有理由选择其中一种方式而不是另一种吗?

 if (key in object)


if (object.hasOwnProperty(key))
72754 次浏览

in还将检查继承的属性,而hasOwnProperty则不是这样。

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

a in b

vs

b.hasOwnProperty(a)

不管怎样,正如@AndreMeinhold所说,它们并不总是产生相同的结果。

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

如果key原型链中找到,in也将返回true,而Object.hasOwnProperty(就像它的名字已经告诉我们的那样)只会返回true,如果key在该对象上直接可用(它“拥有”该属性)。

另一种形式(in调用)枚举属性名(或键) 物体的。控件中的另一个属性名字符串 对象被赋值给变量。通常需要测试 object.hasOwnProperty(变量)来确定属性名是否

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

(来自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()没有在原型中查找,而in在原型中查找。

摘自O'Reilly高性能Javascript:

你可以确定一个对象是否有一个实例成员 使用hasOwnProperty()方法,并传入 成员名。来确定对象是否具有对对象的访问权 属性,则可以使用in操作符。例如:< / p >

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
在这段代码中,当传入" title "时,hasOwnProperty()返回true 因为title是一个对象实例;时,该方法返回false 传入" toString "是因为它在实例中不存在。当 每个属性名与in操作符一起使用,结果为真 两次都是因为它搜索实例和原型
你的回答非常棒。 我只是想提供一些东西,将节省您在迭代对象时检查“hasOwnProperty”的需要

当创建一个对象时,人们通常会这样创建:

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

现在,如果你想通过“someMap”进行迭代,你必须这样做:

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

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

如果你想创建一个简单的对象,它只会被用作“map”(即键值对),你可以这样做:

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
}

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

正如其他答案所指出的,hasOwnProperty将检查对象自身的属性,而in也将检查继承的属性。

新方法2021 - Object.hasOwn()替换Object.hasOwnProperty()

Object.hasOwn()旨在作为Object.hasOwnProperty()的替代品,是一个可用的新方法(但仍然不是所有浏览器都完全支持,如你在这里看到的- https://caniuse.com/?search=hasOwn ) < / p >

Object.hasOwn()是一个静态方法,如果指定对象将指定的属性作为自己的属性,则返回true。如果该属性被继承,或不存在,则该方法返回false。

const person = { name: 'dan' };


console.log(Object.hasOwn(person, 'name'));// true
console.log(Object.hasOwn(person, 'age'));// false


const person2 = Object.create({gender: 'male'});


console.log(Object.hasOwn(person2, 'gender'));// false

建议在Object.hasOwnProperty()上使用此方法,因为它也适用于使用Object.create(null)创建的对象和覆盖继承的hasOwnProperty()方法的对象。虽然可以通过在外部对象上调用Object.prototype.hasOwnProperty()来解决这类问题,但Object.hasOwn()克服了这些问题,因此是首选方法(参见下面的示例)

let person = {
hasOwnProperty: function() {
return false;
},
age: 35
};


if (Object.hasOwn(person, 'age')) {
console.log(person.age); // true - the remplementation of hasOwnProperty() did not affect the Object
}

let person = Object.create(null);
person.age = 35;
if (Object.hasOwn(person, 'age')) {
console.log(person.age); // true - works regardless of how the object was created
}

关于Object.hasOwn的更多信息可以在这里找到:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn

浏览器兼容性——https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn#browser_compatibility

另一种只有自己属性的方法是:

<script type="text/javascript">"use strict";
const obj = Object.create({cle:"valeur"});
obj.a = "aaa";
obj.b = "bbb";
obj.c = "ccc";


for(let key=0 ; key < Object.keys(obj).length ; key++){
if(Object.keys(obj)[key]==="cle")
console.log(key , Object.keys(obj)[key] , Object.values(obj)[key]);
// none


if(Object.keys(obj)[key]==="b")
console.log(key , Object.keys(obj)[key] , Object.values(obj)[key]);
// 1   'b'   'bbb'


console.log(key , Object.keys(obj)[key] , Object.values(obj)[key]);
// 0   'a'   'aaa'
// 1   'b'   'bbb'
// 2   'c'   'ccc'
}


console.log(Object.getOwnPropertyDescriptor(obj,"cle"));
// undefined


console.log(Object.getOwnPropertyDescriptor(obj,"c"));
// {value:'ccc', writable:true, enumerable:true, configurable:true}
</script>