Follow that __proto__!
June 28, 2019
Programmers new to JavaScript are often confused by concepts such as callbacks, scoping rules, the number of methods/functions available to JavaScript objects,
and other features of the JavaScript language. However, it is important for programmers to understand what is going on "under the hood" in order to be an effective programmer.
In JavaScript, functions are first-class objects meaning they can have properties and methods like any other object. This has implications for how JavaScript creates
and manages certain attributes and objects using keywords such as new or methods like Object.create().
At the risk of starting a programming holy war JavaScript is not a true object oriented language. However, a lot of syntactic sugar
has been added to the language so JavaScript looks and acts very much like a true object oriented language. JavaScript achieves this in large
part through the automatic creation of a __proto__ attribute whenever an object is created. The __proto__ property of an object is a reference to the class or function
from which the object is created using the keyword new or Object.create(). The latter overrides
the default __proto__ reference to Object.prototype and replaces it with a reference to the object passed into create (null can be passed as an argument as well).
When a function is invoked on an object, JavaScript looks at the object and checks to see if the function is available, and the function is executed if
it exists. If the function is not a direct attribute of the object JavaScript follows the __proto__ reference to the prototype property of the appropriate object. This is
normally the function or class from which the object is instantiated from, but programmers have the ability to change their __proto__ reference...which I don't recommend as doing so
can have unintended consequences. The __proto__ chain is traversed until the function is found or JavaScript's global object, from which all objects are inherited is reached.
The prototype property is the default created by JavaScript, and it is stored on the object portion of a function. All JavaScript objects have a __proto__ property so there
is not one direct chain running from a given object to the global object. This should make sense using family trees as a comparison. Every person has two
parents resulting in multiple branches with every successive generation. Similarly, every JavaScript object has a __proto__ attribute (including functions because
they are also objects and objects can consist of multiple objects. The ultimate end is reached with the global Object; Object.prototype.__proto__ === null evaluates to true.
These concepts are fairly complicated, but they are much more understandable through the used of a simple example. Below are three different code examples which do the exact same thing. The first approach requires us to code everything, the second code example is a blend of the "old school" way of JavaScript programming and the third example is the "object oriented" way of JavaScript:

Let's walk through the JavaScript sequence when the first code example is executed:

- JavaScript assigns the function
Officera reference in global memory, but it does not execute the function. - JavaScript assigns the
OfficerFunctionsobject a reference in global memory with two functions; str and promote. - We declare the variable
officerand JavaScript assigns a new local execution space with its own memory. At this pointofficerdoes not have a value and will not have one until the value is returned from the new context. - A new empty
Officerobject is created and thename,rank,branch, anddateofRankarguments are assigned - The invocation of
Object.create(OfficerFunctions)causes JavaScript to create a__proto__reference to theOffcerFunctionsobject.OfficerFunctionsis also an object so it has a__proto__reference toObject.prototypewhich means any Officer object will be able to invoke functions/methods provided byObject. Note that each object created from Officer does not get its own copy of the functions because that's not the case. The reference is a pointer toOfficerFunctionswhich allows the functions to be executed by multipe Officer objects. - The command
return newOfficerinstructs JavaScript to return the value of the new object from the local execution context and assign it to the variableofficerdefined in global memory. - JavaScript executes the
promotefunction on theofficerobject althoughofficerdoes not have its own copy of the function. However,officerdoes have a reference toOfficerFunctionsthru its__proto__property and is thus able to execute thepromotefunction. - We next run
officer.str()which executes thestrfunction via the__proto__chain and we see that 2LT Grey Hog has been successfully promoted to 1LT! - The purpose of
console.log(officer.__proto__)from within the Chrome Dev Tools is to show the methods available to ourofficerobject, and you can see there is yet another__proto__object which provides even more "bonus" features and functionality available to our object courtesy of the JavaScript language.
Take a closer look at the promote function and you will soon we have an inner function named reallyPromote() defined. There's no real reason to define an inner function, but I include it is a good example of an "arrow" function using ES6 syntax. Defining an arrow function is easier (once you get used to it), but that's not the main benefit. In this case we want to take advantage of the fact that arrow functions use lexical scoping, and one of the benefits of lexical scoping is nested functions have access to variables declared in their outer scope. This is an extremely important concept because it allows us to use closures to achieve object oriented behavior such as encapsulation. A closure is the combination of a function and the lexical environment within which that function was declared. We will leave it at that as lexical scoping and closures are worthy of their own lengthy blog post. If you want to learn more I recommend an excellent MDN blog on the topic at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures. The concept is raised here as it is fundamental to how JavaScript implements its object oriented behavior which is not the same as true object oriented languages such as C++.
Let's turn our attention to the second code snippet:

The new keyword automates a lot of code that would otherwise have to be explicitly written by a programmer including:
- Creates an object referred to as
thisin the local execution context - Creates a
__proto__reference to the prototype property of the invoking object - Automatically returns an object to the invoking context
The concept of this is very important and will be very familiar to those experienced with object oriented languages
such as C++. this is an implicit reference to the current object and this always refers to the object to the left of the dot
on which the function (method) is being called unless it is overridden by running the function using .call() or .apply().
This is JavaScript's way of allowing one object to run a function/method belonging to another object. Note - The only
difference between call() and apply() is the way arguments are passed into the function - call expects arguments
to be separated by commas and apply expects arguments to be passed in as an array. But I stray. Let's review the code below:
function Officer(name, rank, branch, dateOfRank) {
this.name = name;
this.rank = rank;
this.branch = branch;
this.dateOfRank = new Date(dateOfRank)
}
Officer.prototype.str = function() {
console.log(this.rank + " " + this.name + "\nBranch: " + this.branch + "\nDate of Rank: " + this.dateOfRank );
}
Officer.prototype.promote = function() {
...
}
We can see our code is starting to get easier to read thanks to our use of the new keyword. We don't have to create a new object
within the Officer function and we assign the passed in arguments to the this object which was instantiated in the new execution
context. The str and promote functions are defined within the Officer function object's (remember functions are also first class
JavaScript objects) prototype object. JavaScript automatically creates a __proto__ reference to Officer when a new Officer object
is created which allows us to invoke the functions defined within Officer.prototype when we need them. By now it should be obvious, but it's
worth repeating, that JavaScript has also added a __proto__ reference within Officer.prototype since our prototype is a unique object in its
own right. Look how much better it looks when we take advantage of JavaScript's class keyword...now our code is starting to look like real
object oriented code!
class Officer {
constructor(name, rank, branch, dateOfRank) {
this.name = name;
this.rank = rank;
this.branch = branch;
this.dateOfRank = new Date(dateOfRank)
}
str() {
console.log(this.rank + " " + this.name + "\nBranch: " + this.branch + "\nDate of Rank: " + this.dateOfRank );
}
promote() {
...
}
}
We have already seen the benefits afforded us by the new keyword and things only get better when we use the class keyword. This nice lump of syntactic sugar enables us to
define a constructor and place our str and promote methods (functions) within the Officer class definition. But don't be fooled...behind the scenes JavaScript is up to its
old tricks! Let's take a look at what is going on under the hood:

If this diagram looks suspiciously like the second diagram that's because they are virtually the same...and there isn't much difference between the diagram above and the first one.
That shouldn't be a surprise since by now we know JavaScript, while providing progressive layers of abstraction, is doing the same thing when it runs the code. The class keyword
allows us to group all methods within the class definition, and then puts them in the class prototype property which itself is an object. JavaScript adds the __proto__ property to
each object instantiated from the Officer class and we are free to remain blissfully ignorant of that fact. But if you're like me you prefer to know how things are actually working because
it makes debugging much easier. I included a snip from Chrome which shows officer.__proto__ is the same as Officer.prototype. That doesn't mean the officer object has a copy of the methods
defined within the Officer class because that's not the case (officer.__proto__ is a reference). Otherwise, our program would suffer horrible performance if we instantiated tens of thousands
of officer objects.
Hopefully you have a better understanding of the importance of an object's __proto__ property even if you never have to explicitly use it because without it JavaScript would be unable
to follow the prototype chain and provide inheritance-like capability within the language. The last code snippet introduces the object oriented features of JavaScript although we saw
there isn't much difference under the hood. The differences start to become more pronounced when programmers start to sub-class with the keyword extends, but that is beyond the scope of this blog.
