My goal is that this will help people understand the strengths and weaknesses of each technique and understand what's really going on.
Now let's define a new class of objects called Squares that inherit from Rectangles. To do inheritance, the constructor's
prototype has to inherit from the parent constructor's
prototype. Here we're overriding
getPerimeter to make it slightly more efficient and to show how to override functions.
Usage is straightforward. Just create an instance of each and call a function on each.
This is the resulting data structure. Dashed lines mean object inheritance.
Notice that there is little difference between the
rect instance and
Square.prototype. They are both simply objects that inherit from
Pure Prototypal Objects
Let's do the same example, but without using constructor functions. This time we'll just use plain prototypal inheritance.
Let's define a Rectangle prototype that the base pattern for all our objects.
Now let's define a sub-object called Square that overrides some of the properties to change the behavior.
To create actual instances of these prototypes, we simply create new objects that inherit from the prototype objects and then set their local state manually.
Here is the resultant graph of objects.
One of my favorite methods for creating objects is to use a factory function. The difference is that instead of defining a prototype object with all my shared functions and then creating instances of those, I simply call a function that returns a new object every time.
This example is a super simple MVC system. The controller function takes in as parameters the model and view objects and outputs a new controller object. All state is stored in the closure via the scope.
To use this, simply call the function with the desired parameters. Notice how we can use these directly as event handlers (setTimeout) without having to first bind the function to the object. Since it (the function) doesn't use
this internally, there is no need to mess with the value of
// Output View now has 5 View now has 6 View now has 5 Saving value 5 somewhere Now hiding view
Here is the object graph that results from this code. Notice that we have access to the two passed in anonymous objects via the hidden
[scope] property of the functions. Or in other words, we have access to
view from the closure created by the factory function.
There is so much more I want to explore, but I like to keep these articles somewhat short and bite-size. If there is demand, I'll write a part three explaining how to do ruby-style mixins and other advanced topics.