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
}