Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Alright Agent Kay, I'll approach this question in a different way than Esailija did. Let's begin with simple objects. For example say you already have an object called <code>gandalf</code>:</p> <pre><code>var gandalf = { color: "grey", comeBack: function () { this.color = "white"; return this; } }; </code></pre> <p>There are no constructors in this code. Hence this code is easy to understand. Am I right or am I right?</p> <hr> <p>Alright, now I'm going to do something awesome. I'll create <code>radagast</code> from <code>gandalf</code>:</p> <pre><code>var radagast = Object.create(gandalf); radagast.color = "brown"; </code></pre> <p>What's happening here? Let's break it up:</p> <ol> <li>We create a new object called <code>radagast</code> from <code>gandalf</code> using <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create" rel="nofollow" title="Object.create - JavaScript | MDN"><code>Object.create</code></a>. Hence <code>radagast</code> inherits from <code>gandalf</code>.</li> <li>We set the <code>color</code> of <code>radagast</code> to brown instead of grey.</li> </ol> <p>To make it even more simple imagine you and I had the following conversation:</p> <p><code>I: Hey Agent Kay, I met Radagast yesterday.</code></p> <p><code>U: Who's Radagast?</code></p> <p><code>I: Hmm... do you know who's Gandalf?</code></p> <p><code>U: Yes, I do.</code></p> <p><code>I: Well Radagast is just like Gandalf except that he's brown instead of white.</code></p> <p>This is exactly how inheritance works in JavaScript. You see JavaScript has prototypal inheritance. In prototypal inheritance objects inherits from other objects. In this case <code>radagast</code> inherited from <code>gandalf</code>.</p> <hr> <p>Now they way prototypal inheritance is usually implemented in JavaScript is weird. I call it the <a href="http://aaditmshah.github.io/why-prototypal-inheritance-matters/#constructors_vs_prototypes" rel="nofollow" title="Aadit M Shah | Why Prototypal Inheritance Matters">constructor pattern of prototypal inheritance</a>. For example, take your code:</p> <pre><code>function Gandalf() { this.color = "grey"; } Gandalf.prototype.comeBack = function() { this.color = "white"; return this; }; </code></pre> <p>Now when you create an instance of <code>Gandalf</code> what object does the instance inherit from? It inherits from <code>Gandalf.prototype</code>:</p> <pre><code>var gandalf = new Gandalf; alert(Object.getPrototypeOf(gandalf) === Gandalf.prototype); // true </code></pre> <p>What's happening when you say <code>new Gandalf</code> is:</p> <pre><code>var gandalf = Object.create(Gandalf.prototype); Gandalf.call(gandalf); </code></pre> <p>If you expand <code>Gandalf.call(gandalf)</code> the you get:</p> <pre><code>var gandalf = Object.create(Gandalf.prototype); gandalf.color = "grey"; </code></pre> <hr> <p>Now take your second example:</p> <pre><code>function Gandalf() { this.color = "grey"; this.comeBack = function() { this.color = "white"; return this; }; } </code></pre> <p>In this case when you create an instance of <code>Gandalf</code> you're essentially doing this:</p> <pre><code>var gandalf = Object.create(Gandalf.prototype); gandalf.color = "grey"; gandalf.comeBack = function () { this.color = "white"; return this; }; </code></pre> <p>Hence every time you create a new <code>Gandalf</code> you create a new function <code>comeBack</code>. Thus if you call <code>new Gandalf</code> 10 times you'll have 10 different <code>comeBack</code> functions as well.</p> <p>Compared to this in the first example since <code>comeBack</code> is defined on <code>Gandalf.prototype</code>, every time we call <code>new Gandalf</code> we get a new object which inherits from <code>Gandalf.prototype</code>. Hence there's only one <code>comeBack</code> function which is shared amongst all instances of <code>Gandalf</code>. Isn't that better?</p> <hr> <p>Essentially think of your first example like this:</p> <pre><code>var gandalfPrototype = { create: function () { var gandalf = Object.create(this); gandalf.color = "grey"; return gandalf; }, comeBack: function () { this.color = "white"; return this; } }; var gandalf = gandalfPrototype.create(); // there's only one comeBack function </code></pre> <p>Similarly your second example is equivalent to this:</p> <pre><code>var gandalfPrototype = { create: function () { var gandalf = Object.create(this); gandalf.color = "grey"; gandalf.comeBack = function () { this.color = "white"; return this; }; return gandalf; } }; var gandalf = gandalfPrototype.create(); // there's 1 comeBack for each instance </code></pre> <p>Remember that when you use <code>new</code> before a function call you're actually inheriting from the <code>prototype</code> of the function. Not the function itself.</p> <hr> <p>Finally I would like to say (because I'm a big fan of J.R.R. Tolkien) that this is the way I would write your code:</p> <pre><code>var wizard = { create: function (color) { var wizard = Object.create(this); wizard.color = color; return wizard; } }; var gandalf = wizard.create("grey"); gandalf.comeBack = function () { this.color = "white"; return this; }; var saruman = wizard.create("white"); var radagast = wizard.create("brown"); </code></pre> <p>Thank you for reading my answer.</p>
    singulars
    1. This table or related slice is empty.
    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. 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