我的困境涉及JavaScript的Prototypal Inheritance和hasOwnProperty方法

基本上每个人在JavaScript中写关于成员枚举的人都大力提倡使用
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
,因为
age
mary
的唯一直接成员......另外两个成员
name
surname
在原型链上。 但显然,我希望所有3个成员都在
for..in
构造中迭代;但是如果你删除了
hasOwnProperty
,那么你可以从
Object.Prototype
获得成员,如果有人添加了它的功能。 所以这就是我的困境。 您是否将原型继承与
hasOwnProperty
方法结合使用,但是在枚举过程中冒险获得链上太远的成员? 或者您是否使用其他形式的继承将成员直接添加到对象而不是原型?     
已邀请:
嗯。你说“在原型链中非常接近”,但实际上,这意味着什么非常接近?是三级深度“接近”还是“远”。 无论如何,你可以改变一个beget函​​数并为每个对象实现自己的hasOwnProperty函数,它只会通过原型链直到Object级别。这将解决您通过不使用hasOwnProperty获取添加到Object.prototype的成员的困境。附件代码如下:
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
    
如果你需要迭代一个对象的原型链,你可以使用
hasOwnProperty
跳过直接成员(如你所说)。这当然也会遍历添加到该对象原型中的任何其他成员(
Object.Prototype
等......)。没有办法避免这种情况。 这就像是在询问如何避免枚举
car = {yellow, green, black}
对象的某些成员(伪代码)......你不是......你只是根据它们的价值跳过某些成员。 直接向对象添加成员实际上并不是一种继承形式,除非您使用
begetObject()
技术创建对象...因为它使用Prototype添加成员。     

要回复问题请先登录注册