Published 2020-07-09 by Daniel Bark
Simplifying Javascript Prototypes and the “new” keyword
JavaScript is a prototype based language. The language has a not so common but powerful feature that you can create objects directly without classes or other abstractions. This is a core part of the language.
All JavaScript objects inherit properties and methods from a prototype where Object.prototype is on the top of the prototype inheritance chain.
I will refer to a link in this chain with [[Prototype]]. So whenever you see [[Prototype]] think of it as a link between one object to another.
Side note: [[Prototype]] is called “__proto__” in most but not all Javascript environments.
To dig further down into the Javascript prototype it would be a good idea to take a look at the “new” operator.
When you use the “new” keyword 5 things happen:
- A new object is created. The type of this object is simply object.
2. On this new object, the [[Prototype]] property is set to be the constructor function’s prototype object.
3. The “this” variable is set to point to the newly created object.
4. It executes the constructor function, using the newly created object whenever “this” is being used.
5. Unless the constructor function returns an object reference, the newly created object is returned.
The hardest step to wrap your head around is probably step two. Every object and function has this [[Prototype]] property and it has a few restrictions. It can only be set at creation time and only read with Object.getPrototypeOf(someObject).
In addition to [[Prototype]], functions also have another property called “prototype”, and this one can be read and changed like we are used to. This property can be used to achieve inherited properties and methods for objects you create. If an undefined property of ourNewThing is requested, Javascript will check the object’s [[Prototype]] object for that property. This is how Javascript achieves something very similar to class inheritance.
Let’s look at the example above. objectCreator is nothing but your standard Javascript. It returns nothing but adds a property called “one ”onto “this” with the value of 1.
objectCreator’s prototype has now been modified with a new property.
With this change in place. Let’s try out our objectCreator constructor function.
What just happened? I can be broken down into four steps:
1. An object was created called createdObject. Being such a newborn object, createdObject is just like what you would get from an object literal {}.
2. The [[Prototype]] property of createdObject gets set to the current value of objectCreator.prototype.
3. The objectCreator function is run, with “this” set to createdObject. As a result, createdObject.one gets set to 1.
4. The freshly created object is returned.
Let’s investigate createdObject by looking at its properties:
createdObject has no property called “two”, therefore JavaScript looks at
its [[Prototype]]. createdObject’s [[Prototype]] is the same as objectCreators.prototype where there is a property of “two” with the value 2.
As you can see, it’s strongly reminiscent of class inheritance.
Now for the grand finale! What happens if we were to change objectCreator.prototype?
If objectCreator.prototype gets assigned a new object value, createdObject’s [[Prototype]] won’t change. BUT! If you
modify properties of objectCreator.prototype, both the
prototype and [[Prototype]] gets modified. Therefore, createdObject has also changed.
Some ending words
Puh! That was a lot to take in. Kudos to you if you made it this far.
In my experience, understanding these concept can take years so would not stress about it. If this was new to you, you will probably understand it, and then get confused. And then understand it again, multiple times.
I hope i convinced you that understanding prototypes, “new” and “this” in Javascript is worth the investment.
Best of luck in your future Javascript endorsements!
Written by Daniel Bark
← Back to blog