代码之家  ›  专栏  ›  技术社区  ›  Andreas Grech

我的困境涉及JavaScript的原型继承和hasOwnProperty方法

  •  2
  • Andreas Grech  · 技术社区  · 15 年前

    hasOwnProperty 方法以避免上原型链。

    我知道这是一种防御性编程,以防止对添加到 Object.prototype

    假设我有以下几点:

    var beget = function (o) { // http://javascript.crockford.com/prototypal.html
        function F() {};
        F.prototype = o;
        return new F();
    };
    
    var john = { name: 'john', surname: 'grech' },
        mary = beget(john),
        p;
    
    mary.age = 42; //augmenting 'mary'
    
    // 'surname' in mary              => true
    // mary.hasOwnProperty('surname') => false
    
    for (p in mary) {
        //skipping over non-direct members, meaning that we also skip members
        //inherited from 'john'
        if (!mary.hasOwnProperty(p)) { 
            continue;
        }
        console.log(p);
    }
    

    在上述示例中,仅 age 将显示,因为 是唯一的直接成员 mary …其他两名成员, name surname

    但是很明显,我希望所有的3个成员在 for..in 拥有自己的财产 ,然后您可以从 Object.Prototype 如果有人给它添加函数。


    所以这就是我的困境。

    您是否将原型继承与 拥有自己的财产

    直接地 而不是原型?

    2 回复  |  直到 15 年前
        1
  •  3
  •   nemisj    15 年前

    嗯,你说的是“非常接近原型链”,但实际上,非常接近是什么意思?三级深是“近”还是“远”。

    不管怎样,您可以更改一点beget函数,为每个对象实现自己的hasOwnProperty函数,它只会通过原型链直到对象级别。这将解决您在获取添加到对象.原型不使用hasOwnProperty。代码如下:

    var beget = function (o) { // http://javascript.crockford.com/prototypal.html
        function F() {
            this.hasOwnProperty = function(key) {
                return (key != "hasOwnProperty" 
                    && Object.prototype.hasOwnProperty.call( this, key ) 
                    || o.hasOwnProperty( key )
                );
            }
        };
    
        F.prototype = o;
        return new F();
    };
    
    var john = { name: 'john', surname: 'grech' },
        mary = beget( john ),
        p    = beget( mary );
    
    mary.age  = 42; //augmenting 'mary'
    mary.name = "mary";
    p.size    = "38";
    
    // testing prototype of Object.
    Object.prototype.not_own = function(){}
    
    for(var i in p) {
        console.debug('Key',i, p.hasOwnProperty(i));
    }
    
    // p.hasOwnProperty("size");    // -> true
    // p.hasOwnProperty("age");     // -> true
    // p.hasOwnProperty("name");    // -> true
    // p.hasOwnProperty("not_own"); // -> false
    
        2
  •  0
  •   Luca Matteis    15 年前

    如果需要迭代对象的原型链,可以使用 hasOwnProperty 跳过直接成员(如你所说)。当然,这也将遍历添加到该对象原型的任何其他成员( Object.Prototype 等等…)。这是无法避免的。

    就像在问如何避免枚举 car = {yellow, green, black} 对象(伪代码)。。。你不。。。您只需根据某些成员的值跳过它们。


    直接地 对一个对象的访问并不是一种真正的继承形式,除非您使用 begetObject()

    推荐文章