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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 03:28:56  来源:igfitidea点击:

Undefined, typeof undefined, hasOwnProperty

javascript

提问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 ifresults 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 jsondata.

此外,在我的上一个项目中,我已经typeof a.c == 'undefined'多次使用来检查json数据中的值。

Now, I know that this is not good way, as some value may be undefinedtoo, 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 hasOwnPropertyor should I change all my typeofwith hasOwnProperty

但我相信,没有价值将是undefined,我可以用typeof a.c == 'undefined'代替hasOwnProperty或者我应该改变我所有的typeofhasOwnProperty

回答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)。

hasOwnPropertyserves 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 === undefinedwill produce an unexpected result if someone has done undefined = 'defined'or some such trick;
  • !('c' in a)is not very readable (IMHO)
  • !a.hasOwnProperty('c')will return falseif the object adoesn't contain a property c, 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, .hasOwnPropertyhas 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, undefinedas 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 undefinedkeyword, too.

一般来说,undefined这样可以重新定义,但我自己还没有遇到过——我也不认为我会这样做。但是,不可能(AFAIK)弄乱typeof. 在这方面,后者是最安全的方式。我确实相信一些古老的浏览器也不能很好地使用undefined关键字。

In resuming: no need to go and replace every single typeofcheck. 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, .hasOwnPorpertyis the safest bet.

在恢复中:无需去更换每张typeof支票。就个人而言:不过,我认为养成使用 的习惯是一种很好的做法.hasOwnProperty。因此,我建议,在可能存在但未定义的属性的情况下,.hasOwnPorperty是最安全的选择。



In response to your comment: yes, typeofwill fit your needs ~95% of the time. .hasOwnPropertywill 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, hasOwnPropertyis 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)什么区别?