【问题标题】:JavaScript hasOwnProperty vs typeofJavaScript hasOwnProperty vs typeof
【发布时间】:2014-12-15 04:03:16
【问题描述】:

我在 Google 上搜索了很多,但找不到我要找的地方:

Benefit of using Object.hasOwnProperty vs testing if Property is undefined

jsperf speedtest

How to determine if Native JavaScript Object has a Property/Method?

.. 和很多其他网站,但这不是我要找的地方。我真正的问题是:

为什么hasOwnProperty 在他的超类(原型)中找不到方法?为什么有人甚至使用hasOwnProperty?它比typeof 慢得多,如果您使用继承,它就不起作用。

..第二个问题:

this 问题中,Barney 回答您必须使用if ('property' in objectVar) 来检查属性是否存在,但没有解释原因。有人知道你为什么要使用这种结构吗?

var objA = function(){};

objA.prototype.alertMessage = function(){
        return 'Hello A';
};

var objB = function(){
    this.hello = function(){
        return 'hello';
    };
};

// Inheritance
objB.prototype  = Object.create(objA.prototype);
objB.prototype.constructor = objA;

var test = new objB();

if (test.hasOwnProperty("alertMessage")){
    console.log("hasOwnProperty: " + test.alertMessage());
}

if (typeof test.alertMessage === "function"){
    console.log("typeof: " + test.alertMessage());
}

if (test.hasOwnProperty("hello")){
    console.log("hasOwnProperty: " + test.hello());
}

if (typeof test.hello === "function"){
    console.log("typeof: " + test.hello());
}

Check out the jsFiddle

【问题讨论】:

  • typeofhasOwnProperty 不相关。 in 运算符用于检查原型链中的属性,而 hasOwnProperty 仅直接检查该对象。如果您关心typeof/hasOwnProperty 的性能,最快的方法可能是简单地使用评估值(因为undefined 评估为false),例如if(test.alertMessage)

标签: javascript prototypal-inheritance


【解决方案1】:

使用hasOwnProperty(在某些情况下必须使用)hasOwnProperty 及其行为的原因有很多:

  • 顾名思义,hasOwnProperty 检查您测试的对象是否拥有具有给定名称的属性。如果它从另一个对象(它的原型)继承了一个方法/属性,那么该属性的所有者不是对象,而是它的原型。因此,该对象没有自己的名为 X 的属性
  • typeof 大部分时间都可以工作,但对象可能看起来像这样:var o = {foo: undefined}。当然,在o.foo 上使用typeof 会产生"undefined",但该对象确实拥有一个名为foo 的属性
  • 使用if ('properyname' in object) 是一种解决方法,它结合了两全其美:在o = {foo: undefined}; 的情况下,它评估为真,而无需查找hasOwnPropery 方法的开销(这是Object.prototype 的一个属性),或者一个带有上下文绑定的函数调用等等。它还会在原型链中找到属性

因此请考虑以下示例:

var o = {foo: undefined,
    toString: undefined};//overwrite inherited method
console.log(typeof o.foo);//undefined
console.log(typeof o.toString);//undefined
console.log(o.hasOwnProperty('toString'));//true
delete(o.toString);
console.log(typeof o.toString);//function
if ('valueOf' in o)
    console.log(o.valueOf === Object.prototype.valueOf);//true
if ('foo' in o)
    console.log(o.foo);//undefined

要注意的另一件重要事情是,您关于hasOwnProperty 在处理继承时不起作用的陈述只是简单的错误。你在 JS 中使用的每个对象都至少继承自一个原型。认识到、理解和尊重这一点很重要。如果您遍历一个对象,建议确保您实际上是在遍历属于该对象本身的属性。因此,这种情况并不少见:

for (p in obj)
{
    if (obj.hasOwnProperty(p))
        //process property
}

这是为了避免代码遍历原型链中的所有属性,这可能会破坏超级对象

if (!Object.prototype.hasProperty)
{//dirty check ;-P
    Object.prototype.hasProperty = (function(OP)
    {
        return function(name)
        {
            //typeof for speed: if value is not undefined, return true
            if (typeof this[name] !== 'undefined' || this.hasOwnProperty(name))
                return true;
            if (this === OP)//we've just checked the Object.prototype, found nothing, so return false
                return false;
            return Object.getPrototypeOf(this).hasProperty(name);//check prototype
        };
    }(Object.prototype));//OP is object prototype
}

【讨论】:

  • 感谢您澄清这一点!第一点很清楚,但是如果他们添加hasProperty 方法会更有意义;) 你们其他人的回答似乎很好,我不知道undefined 'trick'。感谢您指出这一点!
  • @GuyT: 你可以实现一个hasProperty 方法,它使用Object.getPrototypeOf 遍历原型链,直到hasOwnProperty 返回true,或者falseObject.prototype 级别
  • 嗯..这似乎是一个不错的实现!我会看看。谢谢。
  • @GuyT:在我的回答中添加了hasProperty 的可能实现
猜你喜欢
  • 2023-03-12
  • 1970-01-01
  • 2010-09-16
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
  • 2021-01-07
  • 2011-02-11
  • 1970-01-01
相关资源
最近更新 更多