2

基本的に、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が表示されます。これは、 が...他の 2 つのメンバーageの唯一の直接メンバーであり、 と がプロトタイプ チェーンの上にあるためです。marynamesurname

しかし、明らかに、3 つのメンバーすべてを構成内で反復処理する必要がありfor..inます。ただし、を削除すると、誰かが関数を追加した場合hasOwnPropertyにメンバーを取得できます。Object.Prototype


これが私のジレンマです。

プロトタイプの継承をメソッドと組み合わせて使用​​しますが、hasOwnProperty列挙中にチェーンの上位にあるメンバーを取得するリスクがありますか?

それとも、プロトタイプではなくオブジェクトにメンバーを直接追加する他の形式の継承を使用しますか?

4

2 に答える 2

3

うーん。「プロトタイプチェーンに非常に近い」とおっしゃっていますが、実際には、非常に近いとはどういう意味ですか?3つのレベルの深さは「近い」または「遠い」です。

とにかく、少しbeget関数を変更して、すべてのオブジェクトに独自のhasOwnProperty関数を実装できます。これは、オブジェクトレベルまでのみプロトタイプチェーンを通過します。これにより、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
于 2010-09-29T13:38:11.960 に答える
0

オブジェクトのプロトタイプチェーンを反復処理する必要がある場合は、hasOwnProperty直接メンバーをスキップするために使用できます(あなたが言ったように)。もちろん、これは、そのオブジェクトのプロトタイプに追加された他のメンバー (など) を反復処理しますObject.Prototype。これを避ける方法はありません。

オブジェクト (疑似コード)の特定のメンバーの列挙を回避する方法を尋ねるようなものcar = {yellow, green, black}です... そうではありません... 値に基づいて特定のメンバーをスキップするだけです。


オブジェクトにメンバーを直接追加することは、実際には継承の形式ではありません。もちろん、begetObject()テクニックを使用してオブジェクトを作成しない限り...プロトタイプを使用してメンバーを追加するためです。

于 2010-09-29T09:15:32.630 に答える