Every function has a built-in prototype object, when the function is created, it is immediately gets a new object assigned to its prototype property. If we call the function via the new operator, invoking it as a constructor, a newly allocated object has been created and set as the context of the function (and is accessible through the this keyword). The result returned from the new operator is a reference to this new object.
As you can see, a function, when created, gets a new object that’s assigned to its prototype property. The prototype object initially has only one property, constructor, that references back to the function .
When we use a function as a constructor (for example, by calling new Ninja()), the prototype of the newly constructed object is set to the object referenced by the constructor function’s prototype.
Instance properties vs prototype properties
Within the constructor function, the this keyword refers to the newly created object, so the properties added within the constructor are created directly on the new ninja instance. Later, when we access the property swingSword on ninja, there’s no need to traverse the prototype chain (as shown in figure 7.4); the property created within the constructor is immediately found and returned (see figure 7.5).
This has an interesting side effect. Take a look at figure 7.6, which shows the state of the application if we create three ninja instances.
As you can see, every ninja instance gets its own version of the properties that were created within the constructor, while they all have access to the same prototype’s prop- erties. This is okay for value properties (for example, swung) that are specific to each object instance. But in certain cases it might be problematic for methods.
In this example, we’d have three versions of the swingSword method that all per- form the same logic. This isn’t a problem if we create a couple of objects, but it’s something to pay attention to if we plan to create large numbers of objects. Because each method copy behaves the same, creating multiple copies often doesn’t make sense, because it only consumes more memory. Sure, in general, the JavaScript engine might perform some optimizations, but that’s not something to rely on. From that perspective, it makes sense to place object methods only on the function’s prototype, because in that way we have a single method shared by all object instances.
Object typing via constructors
By using the constructor property, we can access the function that was used to create the object. This information can be used as a form of type checking, as shown in the next listing.