7

私は中程度のレベルのJavaScript開発者であり、バックボーンライブラリが内部でどのように機能するかを理解しようとしています。誰かが私にいくつかの課題を解決するのを手伝ってくれれば、深く感謝します。

これが私が理解していることです

バックボーンのコンストラクター関数の基本的な定義は

Backbone.Model = function(attributes, options) { }

次に、汎用のextendメソッドを使用して、コンストラクターのプロトタイプに共通の機能を追加します。

_.extend(Backbone.Model.prototype, Backbone.Events, {...})

この部分まで、私は何が起こっているのかを正確に知っており、次のコードを介して新しいオブジェクトをインスタンス化できれば幸いです

var user = new Backbone.Model() 

これは私が挑戦している部分です

もちろん、Backboneでオブジェクトをインスタンス化する方法ではありませんが、extendメソッドを使用します

var Users = Backbone.Model.extend({});
var user = new Users()

およびバックボーンコード

Backbone.Model.extend = extend;

var extend = function(protoProps, classProps) {
        var child = inherits(this, protoProps, classProps);
        child.extend = this.extend;
        return child;
};

var inherits = function(parent, protoProps, staticProps) {
    var child;
    if (protoProps && protoProps.hasOwnProperty('constructor')) {
        child = protoProps.constructor;
    } else {
        child = function() {
            return parent.apply(this, arguments);
        };
    }
    _.extend(child, parent);
    ctor.prototype = parent.prototype;
    child.prototype = new ctor();
    if (protoProps) _.extend(child.prototype, protoProps);
    if (staticProps) _.extend(child, staticProps);
    child.prototype.constructor = child;
    child.__super__ = parent.prototype;
    return child;
};

継承関数内で何が起こっているのか、拡張メソッドアプローチの利点は何ですか?

4

1 に答える 1

10

アンダースコアのextend関数は、2番目の引数のメンバー(関数とプロパティ)を最初の引数にマージします。例えば:

var reciever = { 
    name: "Jonny",
    age: 29
};

var supplier: {
    languages: [ "javascript", "actionscript" ];
    sayHi: function () { 
        console.log("Hi, name name is " + this.name);
    }
};

_.extend(receiver, supplier);

上記のコードを実行すると、レシーバーオブジェクトが拡張(変更)され、次のようになります。

/*
    {
        age: 29,
        languages: [ "javascript", "actionscript" ],
        name: "Jonny",
        sayHi: <<function>>
    }
*/
console.dir(receiver);

サプライヤオブジェクトは変更されないままであり、レシーバオブジェクトはサプライヤからすべてのプロパティと機能を取得することに注意してください。このプロセスは一般にミックスインと呼ばれ、関数を再宣言する必要をなくすために使用されます(より広いプログラミング原理の一部として、DRY-Do n't Repeat Yourselfを知っています)。

バックボーンのModel.extend関数については、ファクトリメソッドとして機能し、コンストラクタ関数を返します。コンストラクタ関数を使用して、内部inherits関数が作業の大部分を実行するモデルの新しいインスタンスを作成できます。このinherits関数は、ミックスインの概念をさらに一歩進めて、提供されたオブジェクトと親(この特定の場合はオブジェクト)の間に継承チェーンBackbone.Modelを作成します。

var child;
if (protoProps && protoProps.hasOwnProperty('constructor')) {
    child = protoProps.constructor;
} else {
    child = function() {
        return parent.apply(this, arguments);
    };
}

この最初のコードブロックは、提供されたオブジェクトハッシュ内でコンストラクター関数を見つけようとしています。存在しない場合は、新しいコンストラクター関数が作成され、提供された引数が代わりにBackbone.Model独自のコンストラクター関数に自動的に渡されます。

_.extend(child, parent);

次に、アンダースコアのextendメソッドを呼び出して、提供されたプロパティと関数のハッシュからコンストラクター関数にすべてのプロパティと関数をミックスインします。これにより、作成する各インスタンスに独自のデータが含まれるようになります(たとえば、プロパティは静的ではなく、作成するすべてのインスタンスで共有されます)。

ctor.prototype = parent.prototype;
child.prototype = new ctor();
if (protoProps) _.extend(child.prototype, protoProps);
if (staticProps) _.extend(child, staticProps);
child.prototype.constructor = child;
child.__super__ = parent.prototype;

この最後のブロックは最もエキサイティングであり、新しく作成されたコンストラクター関数のプロトタイプと親(Backbone.Model)オブジェクトのプロトタイプの間に関係を作成します。これを行うことにより、コンストラクターによって返されるすべての新しいインスタンスには、プロトタイプチェーンから解決されるときに、通常のバックボーンモデルメソッド(つまり、 getおよびset )が含まれます。この特定のコードブロックについて詳しく知りたい場合は、プロトタイプの継承に関するDouglasCrockfordの記事から始めるのが最適です。

このアプローチのポイントは、結果のコンストラクター関数が青写真として使用するプロパティと関数のハッシュを提供できることです。次に例を示します。

var Person = Backbone.Model.extend({
    name: "Jon Doe",
    sayHi: function () { 
        console.log("Hi, my name is " + this.get("name"));
    }
});

これで、インスタンス化する各オブジェクトには、プロパティと関数Personの両方が含まれます。例:namesayHi

var dave = new Person();
dave.sayHi();   // "Hi, my name is Jon Doe"

dave.set("name", "Dave");
dave.sayHi();   // "Hi, my name is Dave"

// You can also supply properties when invoking the constructor.
var jimmy = new Person({ name: "Jimmy" });
jimmy.sayHi();  // "Hi, my name is Jimmy"
于 2012-08-16T14:11:59.253 に答える