如果您检查作为解析 JSON 字符串结果的标准对象,.hasOwnProperty
则没有明显的好处。当然,除非你或你正在使用的某个库一直在搞乱Object.prototype
.
一般来说,undefined
这样可以重新定义,但我自己没有遇到过 - 我也不认为我会这样做。但是,(AFAIK)不可能弄乱typeof
. 在这方面,后者是最安全的方法。我确实相信一些古老的浏览器也不能很好地使用该undefined
关键字。
在恢复中:无需去更换每张typeof
支票。就个人而言:不过,我认为养成使用 . 的习惯是一种好习惯.hasOwnProperty
。因此,我建议,如果某个属性可能存在但未定义,.hasOwnPorperty
这是最安全的选择。
回应您的评论:是的,typeof
大约 95% 的时间会满足您的需求。.hasOwnProperty
将工作 99% 的时间。但是,正如名称所示:不会检查继承链更高的属性,请考虑以下示例:
Child.prototype = new Parent();
Child.prototype.constructor=Child;//otherwise instance.constructor points to parent
function Parent()
{
this.foo = 'bar';
}
function Child()
{
this.bar = 'baz';
}
var kiddo = new Child();
if (kiddo.hasOwnProperty('foo'))
{
console.log('This code won\'t be executed');
}
if (typeof kiddo.foo !== 'undefined')
{
console.log('This will, foo is a property of Parent');
}
因此,如果您想检查单个对象是否具有属性,hasOwnProperty
这就是您所需要的。特别是如果您要更改该属性的值(如果它是原型属性,则可以更改所有实例)。
如果您想知道一个属性是否有值(除 之外undefined
),无论它位于继承链中的哪个位置,您都需要typeof
. 我在某处有一个递归函数来确定可以在继承链中找到该属性的位置。一旦我找到它,我也会在这里发布它。
更新:
正如所承诺的,在继承链中定位属性的功能。这不是我不久前使用的实际功能,所以我整理了一份工作草案。它并不完美,但它可以很好地帮助您:
function locateProperty(obj,prop,recursion)
{
recursion = recursion || false;
var current = obj.constructor.toString().match(/function\s+(.+?)\s*\(/m)[1];
if (!(obj.hasOwnProperty(prop)))
{
if (current === 'Function' || recursion === current)
{
return false;
}
return locateProperty(new window[current](),prop,current);
}
return current;
}
//using the object kiddo
locateProperty(kiddo,'foo');//returns 'Parent'
locateProperty(kiddo,'bar');//returns 'Parent', too
为避免最后一个故障,您可以将最后一个return current;
语句替换为return obj;
. 或者,更好的是,将以下行添加到上面的代码段中:
Child.prototype.constructor=Child;
我在第一次编辑时忘记了...