it is an embedded scripting language — the language itself doesn’t even have a
standard module system or standard I/O constructs. On the other hand, it
supports both the object-oriented programming and functional programming
paradigms, is the only language reliably available in web browsers, and got
hugely popular over the last several years.
this and new keywords also mean completely different things as compared to
I’m assuming you are a programmer and know a classical OOP language like Java,
however, I am mostly using NodeJS v5.6.0 to check the validity of my examples.
look-up traverses the chain. But how does everything work in concrete terms?
Here are a few prototype-related phrases or keywords:
“The [[Prototype]] property”, e.g. as used in the ES5 spec;
the prototype property on constructor functions, where
“constructor functions” are those functions written to be used with new.
It turns out that among the above, [[Prototype]] and __proto__ actually
refer to the same concept — the “prototype” of an object, where you can try to
look properties up in case the object itself doesn’t have that property. The
prototype property (of constructor functions, usually), on the other hand, is
not the “prototype” of the object holding that property.
We say an object “has a property” if that property can be found in that object
or anywhere on that object’s prototype chain. We say an object “has an own
property” if we can find that property without traversing the object’s prototype
To check whether a given object “has a property”, we can use in:
To check whether a given object “has an own property”, we can use
As an aside, .hasOwnProperty is available on a fresh, default object because
hasOwnProperty is actually a property of Object.prototype, which the
prototypes of all usual objects are set to.
Since ES5, there are a few nice “meta-programming” functions that allow us to do
things with the prototypes of objects:
See these functions in action here:
Constructor functions are functions whose author wrote them with the intention
that the function is called using new. For now, let’s worry so much about what
exactly new does, but focus on the constructor function and the object it
“instance” means in a class-less, prototype-based language.) It turns out what
instanceof does is to traverse the prototype chain.
As seen from the above examples, it seems like the prototype property on
constructor functions is more like some sort of meta-data that the mechanism for
new reads off and Does The Right Thing with. If we put some properties into
Thing.prototype, then all Things will be able to see that property.
One cool thing is since everything is dynamic, even if we retroactively add new
properties into the prototype property of a constructor function, objects that
we’ve already created beforehand using that constructor function can also access
the new property.
We can also add properties that are functions to Thing.prototype to achieve
very classical-OOP-reminiscient effects:
But of course we’ve jumped the gun — we still don’t know what this does yet.
So let’s move on to studying this.
The “this” keyword
If you know about the special arguments object available inside function
definitions, explaining this would be a bit easier.
The thing to pay attention to here is that the value that is stored in the
arguments object inside the body of a function depends on how the function is
called. If the function is called with two arguments, then arguments will hold
two things. If the function is called without any arguments, then
arguments.length will be 0.
Think of this as another special variable like arguments which:
is available inside the body of a function, and
holds a value that is dependent on how the function is called.
Strictly speaking, the this keyword holds a value even if it is accessed from
outside any functions, and there are weird, stupid things like how it sometimes
refers to the global object, depending on whether “strict mode” is active for
that context; for now, let’s focus on using this inside the body of function
definitions, without strict mode.
The thing about this is that its value, instead of depending on the arguments
that are passed to the function when the function is called, depends on the
syntax of the function call expression. I know, it’s weird, right? It makes me
think a little of dynamically-scoped languages, where what a variable name is
not looked-up where the function is defined, but rather where it is called. Some
would call it “very late binding”, where this is not bound even at
run-time, but only bound at call-time. Anyway, let’s see some examples.
Similar to how we have Object.create, Object.getPrototypeOf etc. for dealing
with prototypes, we have the following functions to deal with this:
These functions basically let you explicity specify which object to pass as
this to a given function.
I’ll leave you to read the docs on MDN for the details of, or difference
between, call and apply. I’ll also just mention that in ECMAScript 6,
Arrow Functions also gives new ways of dealing with the this
By now, we can understand why the example from the very first snippet of this
post of pushing elements into an array — where we were trying to pass a method
of an object as a function to a higher-order function — didn’t work as naively
Oops! It turns out that Array.prototype.forEach passes more than
just one argument to its argument function (Array.prototype.push in
this case), so .push pushed all of those arguments in. For details,
read the docs for Array.prototype.forEach.
The “new” keyword
Now that we know how this works, and how prototypes can be set up, we are
equipped to learn about the mechanism for new! What does the new keyword do?
Well, we can just read section 13.2.2 of the ES5 spec. (I found this
when reading StackOverflow about returning values from constructor
functions.) I personally think of new as just syntactic sugar,
into the quirks and details of new as per the spec, here’s overly-simple
learnt so far, that does what we’ve seen new do so far:
This implementation already does a lot of what new does. See it in action:
Although the above implementation is about right, it doesn’t do all of what
the spec specifies. There are many weird, corner cases of how new might be
Constructor by Ben Nadel demonstrates many of such cases. So
let’s read the spec now, and see how to implement a basically-compliant new.
Go read the spec now: 13.2.2 [[Construct]]. Here’s what that
section says new should do, implemented as a function:
Basically, as compared to the overly-simple implementation, this
basically-compliant implementation takes care of the case where the constructor
function’s prototype property holds a non-object value (which it usually
doesn’t, because by default it’s effectively Object.create(Object.prototype)),
or where the constructor function returns an object value (which is usually
doesn’t, because it doesn’t need to return anything).
Read the spec or the code above slowly. Have a think through — this is all
there is to new.
Simulating classical OOP
Classical OOP wants the following things:
closures cleverly, we can achieve that effect. Since closures are not a
Polymorphism is obvious. Everything is dynamic, so the dispatch of method-calls
is dynamic. Duck typing. Yada yada. Easy.
The not-so-obvious one of the three OOP things is inheritance — because, well,
prototypes and constructor functions:
prototype-related building blocks to simulate classical OOP is more idiomatic.
For instance, some people seem to prefer something like
… instead of the
… which I used. My reason for doing what I did is that at time of defining the
SubThing “class”, I may not have enough information to instantiate a Thing,
depending on what arguments the Thing constructor takes.
The point here is, although the above code sample may not be idiomatic, it
nonetheless certainly can get the “simulate classical OOP” job done, nicely,
parts: prototypes, this, and new. Equipped with this knowledge, you are
allegedly still prototype-based) or ES6 arrow functions (which makes this