0

プロトタイプの継承を実装しようとしていますが、その動作を理解していません。

次の例を考えてみましょう。

var config = {
  writable: true,
  enumerable: true,
  configurable: true
};

var defineProperty = function( obj, name, value ) {
  config.value = value;
  Object.defineProperty( obj, name, config );
}

var man = Object.create( null );
defineProperty( man, 'sex', 'male' );

var yehuda = Object.create( man );
defineProperty( yehuda, 'firstName', 'Yehuda' );
defineProperty( yehuda, 'lastName', 'Katz' );

yehuda.sex正しいreturnsにアクセスするとmale、値を更新しようとすると、実際に何が起こるかは、に新しいプロパティが作成sexされyehudaます。

考えられる解決策の1つは、プロトタイププロパティ()に直接アクセスするObject.getPrototypeOf(yehuda).sex = 'female'ことですが、これは、オブジェクトが属するプロパティを知る必要があることを意味します。

4

1 に答える 1

1

プロトタイプを使用するという考え方は、オブジェクトのプロパティにアクセスしようとすると、インタプリタは最初に指定されたオブジェクトのそのプロパティを見つけようとするというものです。

指定されたオブジェクトでプロパティが見つからない場合、インタープリターは、プロトタイプチェーンがで終わるまで、オブジェクトのプロトタイプなどでプロパティを見つけようとしますnull

プロパティが見つからない場合、インタプリタはを返しますundefined。それ以外の場合は、プロパティ値を返します。

あなたの場合、プロパティsexにアクセスしているとき、それはオブジェクトにはありませんが、オブジェクトのプロトタイプにはあります。したがって、を返しますmale

次に、それに新しい値を割り当てると、sexJavaScriptは動的言語であるため、オブジェクトのプロトタイプのプロパティを変更する代わりに、指定されたオブジェクトに新しいプロパティを作成します。

新しい値が古い値をシャドウするため、これは問題ありません。これがプロトタイプの継承の仕組みです。

指定されたオブジェクトではなくプロトタイプのプロパティを明示的に更新する場合は、次のようにオブジェクトにプロパティを作成することをお勧めします。

function defineProperty(object, name, value) {
    Object.defineProperty(object, name, {
        value: value,
        writable: true,
        enumerable: true
    });
}

function extendObject(object) {
    var extendedObject = Object.create(object);

    Object.keys(object).forEach(function (key) {
        Object.defineProperty(extendedObject, key, {
            set: function (value) {
                object[key] = value;
            },
            enumerable: true
        });
    });

    return extendedObject;
}

var man = Object.create(null);
defineProperty(man, "sex", "male");

var yehuda = extendObject(man);
defineProperty(yehuda, "firstName", "Yehuda");
defineProperty(yehuda, "lastName", "Katz");

これで問題が解決するはずです。プロトタイプの継承について詳しく知るには、この回答を読んでください。

編集:プロトタイプの値を変更しようとしないことをお勧めします。これは、多くのオブジェクトが同じプロトタイプを持っている可能性があるためです。プロトタイプの値を変更すると、それに依存するすべてのオブジェクトに変更が反映されます。それがあなたが達成したいことでない限り、私はあなたがプロトタイプチェーンのシャドウイングプロパティでやることを提案します。

注:オブジェクトのプロパティは削除できます。削除したプロパティが別のプロパティをシャドウイングしていた場合、次に同じプロパティ名にアクセスしたときにシャドウイングされたプロパティが使用されます。

于 2012-06-11T12:41:15.243 に答える