Well, Agent Kay, I approach this question differently than Esailia. Let them start with simple objects. For example, you already have an object named gandalf :
var gandalf = { color: "grey", comeBack: function () { this.color = "white"; return this; } };
There are no constructors in this code. Therefore, this code is easy to understand. Am I right or am I right?
OK, now I'm going to do something amazing. I will create radagast from gandalf :
var radagast = Object.create(gandalf); radagast.color = "brown";
What's going on here? Let me break it down:
- We create a new object named
radagast from gandalf using Object.create . Therefore, radagast inherited from gandalf . - We set the
color of radagast to brown instead of gray.
To make this even easier, imagine that you and I had the following conversation:
I: Hey Agent Kay, I met Radagast yesterday.
U: Who Radagast?
I: Hmm... do you know who Gandalf?
U: Yes, I do.
I: Well Radagast is just like Gandalf except that he brown instead of white.
This is how inheritance works in JavaScript. You see that JavaScript has prototype inheritance. In prototypical inheritance, objects are inherited from other objects. In this case, radagast inherited from gandalf .
Now their prototype inheritance path is usually implemented in JavaScript, this is strange. I call this the prototype inheritance constructor template . For example, take the code:
function Gandalf() { this.color = "grey"; } Gandalf.prototype.comeBack = function() { this.color = "white"; return this; };
Now that you are creating a gandalf instance, on which object does the instance inherit? It inherits from Gandalf.prototype :
var gandalf = new Gandalf; alert(Object.getPrototypeOf(gandalf) === Gandalf.prototype);
What happens when you say new Gandalf :
var gandalf = Object.create(Gandalf.prototype); Gandalf.call(gandalf);
If you deploy Gandalf.call(gandalf) , you will get:
var gandalf = Object.create(Gandalf.prototype); gandalf.color = "grey";
Now take the second example:
function Gandalf() { this.color = "grey"; this.comeBack = function() { this.color = "white"; return this; }; }
In this case, when you create the gandalf instance, you basically do this:
var gandalf = Object.create(Gandalf.prototype); gandalf.color = "grey"; gandalf.comeBack = function () { this.color = "white"; return this; };
Therefore, every time you create a new gandalf , you create a new comeBack function. Thus, if you call new Gandalf 10 times, you will have 10 different comeBack functions.
Compared to this, in the first example, since comeBack defined in Gandalf.prototype , each time we call new Gandalf , we get a new object that inherits from Gandalf.prototype . Therefore, there is only one comeBack function that is shared between all gandalf instances. Isn't that better?
Essentially think of your first example:
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();
Similarly, your second example is equivalent to this:
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();
Remember that when using new before the function call, you inherit the function prototype function. Not the function itself.
Finally, I would like to say (because I'm a big fan of JRR Tolkien) that this way I will write your 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");
Thanks for reading my answer.