Hi, I'm Nick. This is my blog. I'm a life-long unschooler living in New York. You can find more about me here.
I help run the Recurse Center (YC'S10).
Follow me @nicholasbs
Many people get tripped up by the
confusion comes from people reasonably expecting
this to work like “this”
does in Java or the way people use “self” in Python. Although
sometimes used to similar effect, it’s nothing like “this” in Java or other
languages. And while it’s a little harder to understand, its behavior isn’t
magic. In fact,
this follows a relatively small set of simple rules. This
post is an explanation of those rules.
runtime environments which will hopefully help you develop a mental model to
There are three types of executable code: Global code, function code, and
eval code. Roughly speaking, global code is code at the top level of your
program that’s not inside any functions, function code is code that’s inside
the body of a function, and eval code is global code evaluated by a call to
The object that
this refers to is redetermined every time control enters
a new execution context and remains fixed until control shifts to a different
context. The value of
this is dependent upon two things: The type of code
being executed (i.e., global, function, or eval) and the caller of that code.
properties include built-in objects like
String, as well as extra
properties provided by the host environment.
In browsers, the global object is the
window object. In Node.js, it’s just
called the “global object.” (I’m going to assume you’re running code in
a browser, however, everything I say should apply to Node.js as well.)
The first rule is simple:
this refers to the global object in all global
code. Since all programs start by executing global code, and
this is fixed
inside of a given execution context, we know that, by default,
this is the
What happens when control shifts to a new execution context? There are only
three cases where the value of
this changes: method invocations, functions
called with the
new operator, and functions called using
I’ll explain each of these in turn.
If we call a function as a property of an object using either dot (i.e.,
obj.foo()) or bracket (i.e.,
this will refer to
the parent object in the body of the function:
This is our second rule:
this refers to the parent object inside function
code if the function is called as a property of the parent.
Note that if we call the same function directly, that is, not as a property of
the parent object,
this does not refer to the
this was not changed when
inc was called, so it still referred to the
global object. When
it was effectively running:
undefined, and adding
new operator creates a new object and sets
this to the new object inside
the function it was called with. For example:
This leads to our third rule:
this in function code invoked using the
operator refers to the newly created object.
Note that there’s nothing special about
F. If we call it without using
this will refer to the global object:
In this case,
F("Oops!") is a regular function call, and
get set to a new object, because no new object is created since the
operator isn’t used.
this remains set to the global object.
apply, which let you
call functions and explicitly set the value of
apply method takes
two arguments: an object to set
this to, and an (optional) array of arguments
to pass to the function:
call method works exactly the same as
apply, but you pass the arguments
individually rather than in an array:
This is our fourth rule:
this is set to the first argument passed to
apply inside function code when that function is called with either
That’s it! You can figure out what object
this refers to by following a few simple rules:
thisrefers to the global object.
thisrefers to the parent object inside that function.
thisrefers to the newly created object inside that function.
thisrefers to the first argument passed to
apply. If the first argument is
nullor not an object,
thisrefers to the global object.
If you understand and follow those four rules, you will always know what
Remember when I said that code evaluated inside
eval is its own type of
executable code? Well, that’s true, and it means that the rules for determining
this refers to inside of eval code are a little more complex.
As a first pass, you might think that
this directly inside eval refers to the
same object as it does in
eval’s caller’s context. For example:
That works likely as you expect it to. However, there are many cases with
this will probably not work as you expect:
runtime implements ECMAScript
this will refer to the global object and the above should print
because it’s an “indirect” call of
eval. That’s what the latest versions of
Chrome and Firefox do. Safari 5.1 actually throws an error (“The ‘this’ value
passed to eval must be the global object from which eval originated”), which
is kosher according to ECMAScript
If you want know how
this works with
eval, you should read Juriy Zaytsev’s
excellent, “Global eval. What are the
learn more about
eval, execution contexts, and direct vs. indirect calls than
you probably ever wanted to know.
In general, you should just avoid using
eval, in which case the
simple rules about
this given previously will always hold true.
This is a somewhat simplified view of things to make developing a basic mental model easier. For a more detailed explanation, read the section starting at page 37 of the ECMAScript Language Specification. I've based this post in large part off of that document, however, my understanding of it is far from perfect or complete, so please let me know (
me @ nicholasbs.net) if I've misunderstood or misrepresented anything.↩