JavaScript is an OOP language based on prototypes, not classes. This is one of the reasons for all this confusion that you can see around: many developers use JS as it was a class.
So you can see many libraries trying to use the class-based language paradigm in JS.
In addition, JS itself lacks some of the traits that inherit, as well as prototype-based, painful ones. For example, before Object.create there was no way to create an object from another object (as the language should be based on the OOP prototype), but only using the function as constructor.
And for this reason, you can see many libraries that are trying to "fix" the language, each in its own way.
So your confusion is normal. Let's say that the βofficialβ way is to use the prototype , function property as a constructor and Object.create to create from an insteance object. However, as mentioned above, in some cases, the code is detailed or lacks functionality, so this procedure often wraps up in some way, and then becomes a matter of personal taste.
Since you are talking about a model, you can take a look at the Trunk model and see if this approach suits you.
Update : to give an example, which I hope will help you clarify, here is the old way to inherit from school using new :
function Model() { this.foo = "foo"; this.array = []; } Model.prototype.foo = ""; Model.prototype.array = null; Model.prototype.doNothing = function() {}; function RestModel() { this.bar = "bar"; } RestModel.prototype = new Model; RestModel.prototype.bar = "" var myModel = new RestModel();
Now, here are the problems:
- The
Model constructor is called only once when RestModel.prototype installed. Therefore, the foo property for each instance of RestModel will be "foo". - Not only that, but all instances of
RestModel will have the same instance of the same array in the this.array property. If you instantiate the Model directly, you have a new array instance for each instance. myModel.constructor Model instead of RestModel . This is because we are redefining prototype with a new instance of Model that contains a constructor equal to Model .- If you want to have a new instance of
RestModel with a lazy constructor call, this is not possible.
I think that there are main points, of course, they are not the only ones. So how to solve these problems? As I said, many people have already done this, and they create a library and framework to limit verbosity. However, to have an idea:
function Model() { this.foo = "foo"; this.array = []; } Model.prototype.foo = ""; Model.prototype.array = null; Model.prototype.doNothing = function() {}; function RestModel() { Model.call(this); this.bar = "bar"; } RestModel.prototype = Object.create(Model.prototype); RestModel.prototype.constructor = RestModel; RestModel.prototype.bar = "" var myModel = new RestModel();
Note that if you do not want to use prototype or function as a constructor, using Object.create you can do this:
var Model = { foo: "", array: null, doNothing: function() {} } var RestModel = Object.create(Model); RestModel.bar = ""; var myModel = Object.create(RestModel);
Or:
var Model = { foo: "", array: null, doNothing: function() {}, init : function () { this.foo = "foo"; this.array = []; }, } var RestModel = Object.create(Model); RestModel.bar = ""; RestModel.init = function () { Model.init.call(this); this.bar = "bar"; } var myModel = Object.create(RestModel); myModel.init();
In this case, you basically mimic the constructor. You can also pass descriptor to Object.create (see docs ), but it becomes more verbose. Most people use a kind of function or extend method (as you probably saw in the Backbone example).
Hope this helps!