Javascript 未定义,未定义类型,hasOwnProperty
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10895288/
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
Undefined, typeof undefined, hasOwnProperty
提问by Jashwant
Take this snippet,
拿这个片段,
var a = {
}
if(typeof a.c === 'undefined'){
console.log('inside if');
}
if(a.c === undefined){
console.log('inside if');
}
Both if
results in true
. Is there any difference in both statements specific to some browsers?
两者的if
结果都是true
。这两种特定于某些浏览器的语句有什么区别吗?
Also, in my last project I have already used typeof a.c == 'undefined'
numerous times to check values in json
data.
此外,在我的上一个项目中,我已经typeof a.c == 'undefined'
多次使用来检查json
数据中的值。
Now, I know that this is not good way, as some value may be undefined
too, so my logic will fail.
现在,我知道这不是一个好方法,因为某些价值可能也是undefined
如此,所以我的逻辑将失败。
I should have used hasOwnProperty
.
我应该使用hasOwnProperty
.
But I am sure that no value will be undefined
, can I use typeof a.c == 'undefined'
in place of hasOwnProperty
or should I change all my typeof
with hasOwnProperty
但我相信,没有价值将是undefined
,我可以用typeof a.c == 'undefined'
代替hasOwnProperty
或者我应该改变我所有的typeof
用hasOwnProperty
回答by Martijn
(UPDATE: You might want to check out this question: variable === undefined vs. typeof variable === "undefined").
(更新:您可能想查看这个问题:变量 === 未定义与 typeof 变量 === "未定义")。
In veryold browsers (Netscape 2, IIRC, and possibly IE 4 or lower), you couldn't compare a value with undefined
, since that caused an error. In any (semi-) modern browser, however, there's no reason to check typeof value === 'undefined'
instead of value === undefined
(except for paranoia that somebody might have redefined the variable undefined
).
在非常旧的浏览器(Netscape 2、IIRC 和可能的 IE 4 或更低版本)中,您无法将值与 进行比较undefined
,因为这会导致错误。然而,在任何(半)现代浏览器中,都没有理由检查typeof value === 'undefined'
而不是value === undefined
(除了怀疑有人可能重新定义了变量undefined
)。
hasOwnProperty
serves a different purpose. It checks if the object has a property with the given name, and not its prototype; i.e. regardless of the inherited properties. If you want to check whether an object contains a certain property, inherited or not, you should use if ('c' in a) {
...
hasOwnProperty
服务于不同的目的。它检查对象是否具有给定名称的属性,而不是它的原型;即不考虑继承的属性。如果你想检查一个对象是否包含某个属性,继承与否,你应该使用if ('c' in a) {
...
But basically, these will probably all work:
但基本上,这些可能都有效:
if (a.c === undefined) console.log('No c in a!');
if (typeof a.c === 'undefined') console.log('No c in a!');
if (!('c' in a)) console.log('No c in a!');
if (!a.hasOwnProperty('c')) console.log('No c in a!');
The main differences being that:
主要区别在于:
a.c === undefined
will produce an unexpected result if someone has doneundefined = 'defined'
or some such trick;!('c' in a)
is not very readable (IMHO)!a.hasOwnProperty('c')
will returnfalse
if the objecta
doesn't contain a propertyc
, but its prototype does.
a.c === undefined
如果有人做了undefined = 'defined'
或一些这样的伎俩,会产生意想不到的结果;!('c' in a)
不是很可读(恕我直言)!a.hasOwnProperty('c')
false
如果对象a
不包含 property将返回c
,但它的原型包含。
Personally, I prefer the first since it's more readable. If you're paranoid and want to avoid the risk of a redefined undefined
, wrap your code in a self-executing anonymous function as follows:
就个人而言,我更喜欢第一个,因为它更具可读性。如果您偏执并希望避免 redefined 的风险undefined
,请将您的代码包装在自执行匿名函数中,如下所示:
(function (undefined) {
// in here, 'undefined' is guaranteed to be undefined. :-)
var a = {
};
})();
回答by Elias Van Ootegem
If your checking standard objects that are the result of parsing a JSON string, .hasOwnProperty
has no obvious benefit. Except, of course, if you or some lib you're using has been messing around with the Object.prototype
.
如果您检查作为解析 JSON 字符串结果的标准对象,则.hasOwnProperty
没有明显的好处。当然,除非您或您正在使用的某些库一直在使用Object.prototype
.
In general, undefined
as such can be redefined, but I haven't encountered this myself - nor do I think I will ever do so. It is, however impossible (AFAIK) to mess up the return values of typeof
. In that respect, the latter is the safest way to go. I do believe some ancient browsers don't work well with the undefined
keyword, too.
一般来说,undefined
这样可以重新定义,但我自己还没有遇到过——我也不认为我会这样做。但是,不可能(AFAIK)弄乱typeof
. 在这方面,后者是最安全的方式。我确实相信一些古老的浏览器也不能很好地使用undefined
关键字。
In resuming: no need to go and replace every single typeof
check. On a personal note: I believe it to be good practice to get in the habit of using .hasOwnProperty
, though. Hence I'd suggest that, in cases a property might exist, yet be undefined, .hasOwnPorperty
is the safest bet.
在恢复中:无需去更换每张typeof
支票。就个人而言:不过,我认为养成使用 的习惯是一种很好的做法.hasOwnProperty
。因此,我建议,在可能存在但未定义的属性的情况下,.hasOwnPorperty
是最安全的选择。
In response to your comment: yes, typeof
will fit your needs ~95% of the time. .hasOwnProperty
will work 99% of times. However, as the name indicates: properties higher up the inheritance chain won't be checked, consider the following example:
回应您的评论:是的,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');
}
So if you want to check if a single object has a property, hasOwnProperty
is what you need. Especially if you're going to change the value of that property (if it's a prototype property, all instances can be altered).
If you want to know if a property has a value (other then undefined
), regardless of where it is situated in the inheritance chain, you'll need typeof
. I've got a recursive function somewhere to determine where the property can be found in the inheritance chain. Once I've found it, I'll post it here, too.
因此,如果您想检查单个对象是否具有属性,hasOwnProperty
这就是您所需要的。特别是如果您要更改该属性的值(如果它是原型属性,则可以更改所有实例)。
如果你想知道一个属性是否有一个值(除了undefined
),不管它在继承链中的什么位置,你都需要typeof
. 我在某处有一个递归函数来确定属性在继承链中的位置。一旦我找到它,我也会把它贴在这里。
Update:
更新:
As promised, the function to locate a property in an inheritance chain. It's not the actual function I used a while back, so I put together a working draft. It's not perfect, but it could well help you on your way:
正如所承诺的,在继承链中定位属性的函数。这不是我之前使用的实际功能,所以我整理了一个工作草案。它并不完美,但它可以很好地帮助您:
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
To avoid this last glitch, you could either replace the last return current;
statement with return obj;
. Or, better still, add the following line to the above snippet:
为了避免这最后一个小故障,您可以将最后一个return current;
语句替换为return obj;
. 或者,更好的是,将以下行添加到上面的代码段中:
Child.prototype.constructor=Child;
I forgot that in the first edit...
我在第一次编辑时忘记了...
回答by user1260701
Copy the enumerable properties of p to o, and return o.
If o and p have a property by the same name, o's property is left alone.
This function does not handle getters and setters or copy attributes.
function merge(o, p) { for(prop in p) { // For all props in p. if (o.hasOwnProperty[prop]) continue; // Except those already in o. o[prop] = p[prop]; // Add the property to o. } return o; }
将 p 的可枚举属性复制到 o,并返回 o。
如果 o 和 p 具有同名的属性,则 o 的属性将被保留。
此函数不处理 getter 和 setter 或复制属性。
function merge(o, p) { for(prop in p) { // For all props in p. if (o.hasOwnProperty[prop]) continue; // Except those already in o. o[prop] = p[prop]; // Add the property to o. } return o; }
What is the difference between o.hasOwnProperty[prop]
and o.hasOwnProperty(prop)
?
o.hasOwnProperty[prop]
和 和有o.hasOwnProperty(prop)
什么区别?