最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - explain backbone object and class creation pattern - Stack Overflow

programmeradmin1浏览0评论

I am moderate level javascript developer who's trying to understand how backbone library work internally and will deeply appreciate if someone help me to resolve some challenges.

so here is what i understand

basic definition of constructor function in Backbone is

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

then they use general purpose extend method to add mon features in our constructor's prototype.

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

now until this part i know exactly what is happening and would be happy to instantiate new object though following code

var user = new Backbone.Model() 

and this is the part i am finding challenging

ofcourse it's not the way we instantiate a object in Backbone but we use extend method

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

and in backbone code

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;
};

please explain me what is happening inside inherit function and what is the benefit of extend method approach

I am moderate level javascript developer who's trying to understand how backbone library work internally and will deeply appreciate if someone help me to resolve some challenges.

so here is what i understand

basic definition of constructor function in Backbone is

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

then they use general purpose extend method to add mon features in our constructor's prototype.

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

now until this part i know exactly what is happening and would be happy to instantiate new object though following code

var user = new Backbone.Model() 

and this is the part i am finding challenging

ofcourse it's not the way we instantiate a object in Backbone but we use extend method

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

and in backbone code

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;
};

please explain me what is happening inside inherit function and what is the benefit of extend method approach

Share Improve this question asked Aug 16, 2012 at 13:22 nitesh sharmanitesh sharma 6012 gold badges6 silver badges16 bronze badges 1
  • Backbone has source with ments: documentcloud.github./backbone/docs/backbone.html Search for the inherits method. They have a nice description. – jForrest Commented Aug 16, 2012 at 14:12
Add a ment  | 

1 Answer 1

Reset to default 10

Underscore's extend function merges the members (functions and properties) from the second argument into the first. For example:

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

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

_.extend(receiver, supplier);

After executing the above code, the receiver object will have been augmented (modified) and now look like this:

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

Note that the supplier object remains unmodified and the receiver object gains all the properties and functions from the supplier. This process is monly referred to as a mixin and is used to avoid having to redeclare functions (as part of a wider programming principle know an DRY - Don't Repeat Yourself).

Now as for Backbone's Model.extend function, it acts as a factory method to return you a Constructor Function which can be used to create new instances of your model with the internal inherits function doing the bulk of the work. The inherits function takes the mixin concept one step further an creates an inheritance chain between the supplied object and a parent (in this particular case, the Backbone.Model object).

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

This first block of code is trying to find a constructor function inside the supplied object hash; if one isn't present then it creates a new Constructor function for you which automatically passes the supplied arguments to Backbone.Model's own constructor function instead.

_.extend(child, parent);

Next we call underscore's extend method to mixin all the properties and functions from the supplied hash of properties and functions into the constructor function; this ensures that each instance you create has it's own data (eg: properties are not static and shared across all instances that you create).

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;

This final block is the most exciting and creates a relationship between the freshly created Constructor function's prototype and the parent (Backbone.Model) object's prototype. By doing this, all new instances returned by the Constructor will contain the usual backbone Model methods (ie: get and set) as they are resolved from the prototype chain. If you want to learn more about this particular block of code, Douglas Crockford's article on Prototypal inheritance is a great place to start.

The point of this approach is that it lets you supply a hash of properties and function which the resulting Constructor function will use as a blueprint, for example:

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

Now each Person object you instantiate will have both a name property and a sayHi function, eg:

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"
发布评论

评论列表(0)

  1. 暂无评论