if(对象中的键)或if(object.hasOwnProperty(key)

2020/10/23 00:02 · javascript ·  · 0评论

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

 if (key in object)

 if (object.hasOwnProperty(key))

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

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

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

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))

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

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

总之,hasOwnProperty()不看原型而in看原型。

取自O'Reilly高性能Javascript

您可以使用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

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

您得到了一些非常好的答案。我只想提供一些可以节省您在迭代对象时检查“ 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
 }
}

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

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

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
}

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

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

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

(摘自Crockford的Javascript:The Good Parts

第一个版本较短(尤其是在最小化代码中将变量重命名的版本)

a in b

b.hasOwnProperty(a)

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

本文地址:http://javascript.askforanswer.com/ifduixiangzhongdejianhuoifobject-hasownpropertykey.html
文章标签:
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!