Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>JavaScript is an OOP language based on prototypes and not classes. That is one of the cause of all this confusion you can see around: a lot of developers use JS as it was a class-based.</p> <p>Therefore, you can see a lot of libraries that trying to use paradigm of a class-based language in JS.</p> <p>In addition, JS itself is lacking of some traits that makes inheritance, also prototype-based, painful. For example, before <code>Object.create</code> there wasn't a way to create an object from another object (as a OOP prototype-based language should do), but only using a <code>function</code> as constructor.</p> <p>And also for that reason, you can see a lot of libraries that are trying to "fix" the language, every one in its own way.</p> <p>So, your confusion is normal. Say that, the "official" way is use <code>prototype</code> property, <code>function</code>s as constructor, and <code>Object.create</code> to create from object's insteance. However, as said above, in some cases the code is verbose or it lacks of functionality, so this procedure is often wrapped somehow, and then it becomes a matter of personal taste.</p> <p>Because you're talking about model, you can take a look to <a href="http://backbonejs.org/#Model-extend">Backbone's Model</a> and see if this approach fits you.</p> <p><strong>Update</strong>: to give some example that I hope helps you to clarify, here the old school inheritance way using <code>new</code>:</p> <pre><code>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(); </code></pre> <p>Now, here the issues:</p> <ol> <li>The constructor of <code>Model</code> is called once, only when the <code>RestModel.prototype</code> is set. Therefore, the <code>foo</code> property for every <code>RestModel</code> instance will be "foo". </li> <li>Not only that, but <em>all</em> <code>RestModel</code> instances will share the same instance of the same array in <code>this.array</code> property. If you create an instance of <code>Model</code> directly, you have a new instance of array for each instances.</li> <li><code>myModel.constructor</code> is <code>Model</code> instead of <code>RestModel</code>. That's because we override <code>prototype</code> with a new instance of <code>Model</code>, that contains <code>constructor</code> equals to <code>Model</code>.</li> <li>If you want to have a new instance of <code>RestModel</code> with a lazy call to the constructor, is not possible.</li> </ol> <p>I think there are the main points, of course they're not the only ones. So, how to solve that issues? As I said, a lot of people did already that, and they create library and frameworks also to limit the verbosity. However, to have an idea:</p> <pre><code>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(); // for lazy constructor call var anotherModel = Object.create(RestModel.prototype); RestModel.call(anotherModel); </code></pre> <p>Notice that if you don't want to use <code>prototype</code> or <code>function</code> as constructor, with <code>Object.create</code> you can do that:</p> <pre><code>var Model = { foo: "", array: null, doNothing: function() {} } var RestModel = Object.create(Model); RestModel.bar = ""; var myModel = Object.create(RestModel); // Assuming you have to set some default values initialize(RestModel); </code></pre> <p>Or:</p> <pre><code>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(); </code></pre> <p>In that case you mimic basically the constructor. You can also pass a <code>descriptor</code> to <code>Object.create</code> (see the <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/create">docs</a>) but it becomes more verbose. Most of the people use a sort of <code>extend</code> function or method (as you probably saw in Backbone example).</p> <p>Hope it helps!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload