3

次のコードが与えられた場合、プロトタイプチェーンがどのように設定されているかを理解するのに苦労しています。

var Model = {
    prototype: {
        init: function(){},
        log: function(){ console.log('instance method log was called') }
    },
    log: function(){ console.log('class method log was called') },
    create: function() {
        var object = Object.create(this);
        object.parent = this;
        object.prototype = object.fn = Object.create(this.prototype);
        return object;
    },
    init: function() {
        var instance = Object.create(this.prototype);
        instance.parent = this;
        instance.init.apply(instance, arguments);
        return instance;
    }
}

var User = Model.create();
User.log(); // 'class method log was called'

// create a new method after creation
Model.warn = function() { console.warn('warn was called') }

User.warn() // 'warn was called'

var user = User.init();
user.log(); // 'instance method log was called'

具体的には、この行は create メソッドで私を混乱させます:

object.prototype = object.fn = Object.create(this.prototype);

create メソッドがプロトタイプの Model を指す新しいオブジェクトを作成する方法を理解していますが、最後から 2 番目の行はそのプロトタイプを新しいオブジェクト (Model.prototype) で上書きしているようです。ただし、新しいオブジェクトを作成した後でも Model にメソッドを追加でき、新しいオブジェクトは引き続きそれにアクセスできるため、元のプロトタイプはまだそのままのようです。

誰かが実際に何が起こっているのかを明らかにすることができますか?

編集- このコードは、 O'reilly によるJavascript Web アプリケーションからのものであることを指摘しておきます。

4

1 に答える 1

3

Ok。したがって、ノイズコードを削除するためだけに、このコードについて質問しています:

var Model = {
    prototype: {},
    create: function() {
        var object = Object.create(this);
        object.prototype = Object.create(this.prototype);
        return object;
    }
};

Model.create() 関数の最初の行は簡単で、Model を拡張 (プロトタイプ) する新しいオブジェクトを作成します。

しかし、次の行がオブジェクトの「prototype」プロパティを上書きするので、あなたは困惑しています。これはオブジェクトのプロトタイプではなく、オブジェクトのプロトタイプは依然としてモデルであり、[[Prototype]] という隠しプロパティに格納されています。コードが変更しているプロパティは、オブジェクトの [[Prototype]] とは何の関係もありません。名前。それを理解するために名前を変更しましょう。同じになります。

var Model = {
    blablabla: {},
    create: function() {
        var object = Object.create(this);
        object.blablabla = Object.create(this.blablabla);
        return object;
    }
};

Model.blablabla を拡張するため、object.blablabla を変更しても Model.blablabla には影響しません。

var SubModel = Model.create();
SubModel.blablabla.newMethod = function() { };
console.log(Model.blablabla.newMethod); // undefined

多くの場合、フィールドに適切な名前を選択することは、見た目よりも重要です。

于 2012-10-04T21:52:55.167 に答える