
“This” in JavaScript - alphabetam
http://bjorn.tipling.com/all-this
======
couchand
The author critically misunderstands the way that `this` gets set, and in
doing so has developed a significantly overcomplicated mental model. This is
exemplified in the statement:

 _You can use this in any function on an object to refer to other properties
on that object. This is not the same as an instance created with new. ...
Note, there was no use of new , no Object.create and no function called to
create obj._

This is exactly the same behavior that you see on an object method reference,
and drawing any distinction at all makes understanding the behavior of _this_
harder than it needs to be.

In nearly every case (with the exception of _bind_ , _call_ and _apply_ ) the
_this_ variable is set at the CALL SITE of the function, NOT THE DEFINITION.
Note that in the three other cases, you still aren't setting _this_ at the
definition.

The reason you get _this_ behaving as the author describes on objects created
with _new_ is only (as the author nearly, but not quite, realizes) because you
called the function in the form:

    
    
        thing.method()
    

Specifically, it is the object reference that sets the _this_ context within
the method call.

You can be sure that the object literal case is just the same. You don't need
to call _new_ to get an object reference that has a prototype chain: namely,
an object literal is instantiated with the prototype _Object_. You can verify
this is true with a simple:

    
    
        thing = {}
        thing.hasOwnProperty === Object.hasOwnProperty
    

...and so forth.

~~~
xiaoma
Even more simply, I'd just say:

1) The keyword "this" refers to whatever is left of the dot at call-time.

2) If there's nothing to the left of the dot, then "this" is the root scope
(e.g. Window).

3) A few functions change the behavior of "this"— _bind_ , _call_ and _apply_

4) The keyword "new" binds this to the object just created

So if you're using the value of "this" in someFunction...

    
    
      thing.someFunction(); // this === thing
      someFunction();       // this === Window
      new someFunction();   // this === the newly created object
    

It's as simple as that. It's a very useful keyword.

~~~
no_gravity
Can this model explain what "this" is in the context of an event handler?

    
    
        o={ f: function() setTimeout(1000,console.log(this)) }
        o.f()
    

[http://jsfiddle.net/5bh7yot5/](http://jsfiddle.net/5bh7yot5/)

~~~
ingenter
Easily.

But first, let me fix some errors in your code.

You probably meant to write syntactically correct code, so first line changes
to following:

    
    
        o={ f: function() { setTimeout(1000,console.log(this)) } }
    

Then, you probably meant to call console.log after one second, not running it
immediately and passing result to timeout argument, and passing 1000 as a
callback argument.

So the code changes to:

    
    
        o={ f: function() { setTimeout(function() { console.log(this); }, 1000); } }
        o.f()
    

Okay. So what happens now is that

\- You create and object with property 'f'

\- You call the function stored within that property

\- Within Execution Context of that function call, `this` is going to be equal
to our object. Note that we have not yet used `this`.

\- We call setTimeout, passing it function as a callback.

\- After one second, that function is called, with _new_ Execution Context,
not equal to the first one. `this` there is equal to global scope variable.

------
TazeTSchnitzel
This post is way, way too long. Rather than explaining the simple principles
that lead to the behaviour JS's this has, the post just lists example after
example.

JS 'this' is a variable defined within a function. If that function is called
as if it were a method, e.g. obj.somefunc(), 'this' is that object, obj.
Otherwise, 'this' is the global object (quirks mode) or undefined (strict
mode). If a function is called with the new keyword, 'this' is set to a new
object whose prototype is set to the property named 'prototype' on the
function.

The prototype of an object is a fallback: if you try to read a property on an
object and it lacks such a property, it'll grab it from its prototype (or its
prototype's prototype etc.) if it has it. If you write to or create a property
on an object, it always goes on the object and won't touch the prototype.

The weird behaviour for DOM events isn't weird. It just calls the onclick
method as a method.

~~~
jeswin
Your explanation is way simpler to understand than the lengthy original
article.

Maybe one addition: the value of 'this' inside a function FN can also be set
by a caller of FN by using the form FN.call(this-ptr-value, arg1, arg2, ..)
instead of FN(arg1, arg2, ..)

------
ender7
This is a pretty long article. The concepts you need to know aren't so long:

There are three ways to invoke a function. The meaning of `this` depends on
which method was used:

\- If a function is invoked in the form `foo.func()`, then the value of `this`
is `foo`.

\- If a function is invoked in the form `func()` (sometimes called "bare"),
then the value of `this` is the "root object". In browsers the root object is
`window`, in Node this it's the `global` object [0]. It's easier to make a
bare invocation than you think:

    
    
        var bareFunc = foo.func;
        bareFunc();
    

\- If a function is invoked via the `call()` or `apply()` function, then the
value of `this` is whatever the invocation specifies. For example, in
`func.call(foo)` the value of `this` will be `foo`.

If you ever pass a function to something else as a callback, you have no
guarantee what the value of `this` will be when it is called. For example, if
you register a callback for a click event, the value of `this` is whatever the
caller wants it to be (in this case, it'll be the DOM element that's emitting
the event):

    
    
        function MyFoo(elem) {
          elem.addEventListener('click', this.onClick);
        }
    
        MyFoo.prototype.onClick = function(e) {
          // `this` is whatever the caller wanted it to be
        }
    

You can force `this` to be a specific value by using the `bind()` function:

    
    
        function MyFoo(elem) {
          elem.addEventListener('click', this.onClick.bind(this));
        }
    
        MyFoo.prototype.onClick = function(e) {
          // `this` has been bound to what you think it should be.
        }
    

[0] However, if you're in strict mode, then in either case `this` will be
`undefined`.

~~~
hasenj
It's also worth noting that `bind` is not all that special; it simply returns
a function that calls `apply` and passes the `this` object you specified.

I generally think of `this` as an invisible (sneaky) function parameter. It
can be made more visible by using `call`:

    
    
        fn.call(object, param1, param2, ...);

------
_mtr
Not mentioned are ES6's arrow functions that capture the `this` value of the
enclosing context.

[https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)

~~~
AnkhMorporkian
I think the new arrow functions are neat, but am I the only one who never
really found it a hassle to throw a .bind(this) on a function?

~~~
bshimmin
Aside from the fact that your "never" somewhat dismisses the first however
many years of web development (up to IE9) when `Function.prototype.bind`
couldn't universally be expected to be supported, surely having a nice piece
of syntax which is both shorter than writing out `function` _and_ serves the
purpose of binding the function in the way that, a good majority of the time,
you actually want it bound, is a good thing?

As someone who's spent a lot of time writing CoffeeScript, I think ES6's fat
arrows are a great thing, though I have my usual concerns about their
confusing the hell out of people who may well have been writing JavaScript for
a long time but in environments where they don't necessarily get exposed to
new and exciting stuff. But hey, that's progress, I guess.

~~~
AnkhMorporkian
Sure, my .bind was a little insensitive to those who had to suffer through
ES3, but honestly I thought we were pretty much ignoring the 90s.

~~~
bshimmin
You say "the 90s", I say "2011". Potayto, potahto!

------
nmjohn
> JavaScript is not such a language. ... There are many “gotchas”

I don't disagree, like all languages javascript has its quirks (more than
some, fewer than others, all depending on a given developers perspective) but
I fail to see this conclusion being supported by the article itself.

Basically every quirk in it was a result of 'use strict' preventing a
developer from leaking variables (and thus `this`) in ways they shouldn't be
doing - which results in slightly different behavior when strict mode is
enabled. The only real quirk I see here is the fact that strict mode isn't
enabled by default (or better yet not even an option to turn off) but that is
because it would kill backwards compatibility.

'this' in actuality is pretty straightforward - unless you make it complex.
(Which javascript does make it very easy for you to do, which means bad code
will be written doing just that. But bad code is bad code regardless.)

When you define a new function, the contents will have a different scope and
'this' will be different. If you want to access the parent this in a nested
function, you either call the function with the 'this' bound, or you do `var
self=this;` in the parent scope, and use 'self' in lieu of 'this'.

That is pretty much it - I can see how it is a bit tricky at first, but after
spending a bit of time working on javascript it really isn't something you
have to consciously think about too often.

I don't think it is inherently bad, just different. Back when I was writing
Java I would have told you I like their approach better, but now after writing
almost exclusively javascript for the last year or so, I would say I like the
javascript 'this' better. At the end of the day they are just different and a
developer needs to learn the intricacies of whichever language they are
developing in. (Since criticizing javascript is trendy on hn these days, if
you want something to be critical of javascript about that can objectively be
explained, go with the lack of static typing or the related quirky type
coercion in equality checking resulting in (2 == [2]) => true.)

~~~
wycats
> The only real quirk I see here is the fact that strict mode isn't enabled by
> default (or better yet not even an option to turn off) but that is because
> it would kill backwards compatibility

Worth noting: modules in ES6 are "strict by default", which means that most
new code will be in strict mode, without compatibility hazards. Transpilers
emit `"use strict"`, so anyone using one of the ES6 module transpilers is
already writing 100% strict code.

------
drcode
The title of this post alone fills me with anxiety and loathing. The only
title I could think of that would be worse for a post is "Taxes you've been
paying for years but didn't have to".

(great essay BTW on a hated subject :-)

~~~
tricolon
I'm pretty sure "taxes you haven't paid for years but should have" would be
worse.

------
_RPM
I skimmed the article. I began to get anxiety once I realized how long it was.
JavaScript is a very simple language. `this` in JavaScript is easy to
understand. Long posts like this give me anxiety.

~~~
TazeTSchnitzel
It's like an exhaustive, confusing list of examples rather than explaining
briefly the very simple and largely intuitive reasons that lead to these
examples.

------
nchelluri
There's a nice link at the end of the post to another article that is simpler.
I personally liked reading both. Here's the link:
[http://tomhicks.github.io/code/2014/08/11/some-of-
this.html](http://tomhicks.github.io/code/2014/08/11/some-of-this.html)

------
igl
In short: this is a reference to a functions context. If no context is present
it points to the global context or if encapsulated to undefined.

context.func() //this == context

func() // this == global

------
kristiandupont
I hated JS in the beginning, trying to make write it more like I write C# or
C++ (I have experience with other languages, but the syntax lead me to believe
that this style would be best suited). I wrote "self = this" a lot.

Now, I have adopted a much more functional style and I find JS increasingly
pleasant to work with every day. To the point where many of the new ES6
features are a bit worrying because it looks like they want to take it in the
direction of what I wanted it to be when I started. At this point, using
"this" or "prototype" is almost a smell -- they're useful at times but
whenever I use them something in the back of my mind tells me that I could
probably be doing something more elegant.

~~~
CmonDev
Isn't ES6 backwards compatible?

~~~
kristiandupont
Sure, but the standard is going to influence the direction that the language
evolves in, how most libraries are written and so on.

~~~
CmonDev
I agree, it would be better if JavaScript was made even less human-friendly
than it is now. This way the transpilation approach would become mainstream
and people would get a real choice of language instead of an arithmetic
average of language preferences. Thankfully, the Asm.js is making some
important right steps in that direction - and boosting the performance as
well!

------
eric_h
I've used this gist:
[https://gist.github.com/erichummel/2595398](https://gist.github.com/erichummel/2595398)
a few times in interviews to see just how much of a javascript whiz candidates
were.

The basic gist of the interview question is "what is output to the console
when this code is run?"

It's obviously intentionally obfuscated, so even if the candidate got it wrong
(most did), subsequently talking through the solution told me a lot about how
good a candidate was at static analysis and talking through a problem.

~~~
indubitably
Does `setTimeout` have a default value for the time?

~~~
eric_h
setTimeout with no timeout argument simply schedules the provided function for
when the interpreter is next idle. Underscore.js wraps a similar unqualified
call in _.defer (last i checked, anyway; they might now provide it with a very
small number or 0 for the timeout).

Edit: in both cases the result is the same in most browsers.

~~~
ahoge
It's clamped to 4. You can't go lower than that.

There is `setImmediate` for making something run the very next cycle. However,
only IE10+ supports it and the other browser vendors are against it. You can
use abuse `postMessage` to get a similar effect.

------
jMyles
There's something to be said about the distinction between "this" and "self"
as names for the self-referential instance object. While "self" emphasizes
mutability and introspection, "this" evokes a more material, evidentiary
abstraction.

When I transitioned from PHP to Python, the change in nomenclature (albeit
only a social norm in Python) was a big part of what helped me think bigger
about this concept.

To this point, this read might have been easier to digest had it started with
the section "object this."

~~~
userbinator
I personally don't find the terminology has much significance; it wouldn't
matter if it was named "the", "this", "it", "my", or "object", it all refers
to "the object instance upon which this method is invoked".

Maybe it's just because I'm familiar with C where the equivalent of a "this"
reference often has a different name depending on the "class", e.g. "struct
Window * w" or "struct Button * b".

------
vog
The "this" keyword in JavaScript is a well-known anti-pattern. Although it can
be explained with a few rules, it becomes cumbersome quickly.

The anti-pattern around "this" is well-known for decades. For example, SICP
explicitly mentions that anti-pattern. Of course, it doesn't refer to
JavaScript, but to some other old programming language which had a keyword
with very similar issues. I think it's not a hyperbole to say that in this
regard, the JavaScript/ECMAscript language designers haven't learned from the
past.

The main issue is that "this" violates lexical context. Fortunately, the
lexical context is easily restored by declaring a normal variable, usually
named "me", and using the fact that variables have always lexical scope in
JavaScript (as it should be):

    
    
        var me = this;
        someFunctionWithCallback(function() {
            me.something(...);
        });
    

Another workaround is adding a "scope" argument to functions which take
callbacks:

    
    
        someFunctionWithCallback(function() {
            this.something(...);
        }, this);
    

Or:

    
    
        someFunctionWithCallback({
            callback: function() {
                this.something(...);
            },
            scope: this
        });

~~~
ulisesrmzroche
What? No, it's not an anti-pattern. It's about understanding functional
scoping, JavaScript doesn't use lexical scoping.

~~~
vog
Not sure where you got this from. JavaScript does use lexical scoping for
almost everything, except for "this".

~~~
ulisesrmzroche
Yeah, that's what I meant, but it was before caffeine this morning and now its
too late to edit.

------
amitamb
I understood these concepts by reading this book. It is great book for anyone
wanting to go from intermediate to advanced or may be even beginner to
advanced level

[http://www.manning.com/resig/](http://www.manning.com/resig/)

You can go on using Javascript for years without understanding some basic
concepts like "value of this does not depend on where that function is defined
but the way it is called".

------
jpolitz
This topic has come up before on HN, and I ended up writing up a pretty
comprehensive list of ways this can be bound, with references to the spec:

[https://news.ycombinator.com/item?id=4986125](https://news.ycombinator.com/item?id=4986125)

------
pavlov
Maybe, rather than overriding the C++ / Java keyword with a different meaning,
_this_ should have been called something completely else in JavaScript. I
think _context_ would have been more descriptive.

But it's about 17 years late for that...

------
mambodog
Another way of thinking about it is that it's kinda like
Function.prototype.call is being used implicitly at the call site to set the
'context' (the 'this' value):

    
    
        // assuming in each case
        var o = {}
        var o2 = {}
        var fn = function(){}
        
        // 1. bare function call
        fn() // this == undefined in strict mode, global in non strict mode.
        
        // 2. calling with Function.prototype.call
        fn.call(o) // this == o
        
        // 3. 'method' call (calling an object's function property)
        o2.fn = fn
        o2.fn() // this == o2
        // equivalent to
        fn.call(o2)
    
        // 4. calling object's function property with Function.prototype.call
        o2.fn = fn
        o2.fn.call(o) // this == o
    
        // 5. new
        var o3 = new fn() // this = o3
        // equivalent to
        var o3 = Object.create(fn.prototype)
        fn.call(o3)
    
        // 6. calling function bound with Function.prototype.bind
        var fn2 = fn.bind(o)
        fn2() // this == o
        // equivalent to
        var fn2 = function(){ fn.call(o) }
        fn2()
    
        // 7. calling object function property which is a bound function
        o2.fn = fn.bind(o)
        o2.fn() // this == o
        // equivalent to
        o2.fn = function(){ fn.call(o) }
        o2.fn()
        
      

Basically you should think of functions (and 'methods') as not being
intrinsically bound (as in binding-of-'this' bound) to anything.

If you think of a 'method' (function property) as being bound an object purely
by being 'attached' to it then you are gonna have a bad time. Instead, think
of binding of 'this' as usually only happening at call time, to the thing you
are 'calling the function off of'.

In reference to case 1 (bare function call), this is the same behaviour which
occurs when as defining an anonymous function inside a function which has
'this' set. Just don't use 'this' in this case, it doesn't make sense.
Defining a _this or self variable in the parent function is the standard
practice to deal with this case, or in ES6, Coffeescript etc. you have the =>
fat arrow to implicitly do that for you.

------
madlynormal
Check out Kyle Simpson's "You don't know JS" if you really want a clear
understanding on "this" and how it relates to objects in Javascript.
[https://github.com/getify/You-Dont-Know-
JS/tree/master/this%...](https://github.com/getify/You-Dont-Know-
JS/tree/master/this%20%26%20object%20prototypes)

------
wycats
I once wrote a description of `this` from the perspective of `call` as a
"primitive": [http://yehudakatz.com/2011/08/11/understanding-javascript-
fu...](http://yehudakatz.com/2011/08/11/understanding-javascript-function-
invocation-and-this/)

It seemed relevant. :)

------
bshimmin
Tony Hoare has famously described null references as his billion dollar
mistake. Given how often we see articles attempting to explain `this` in
JavaScript (indicative, therefore, of the general level of confusion around
it), I wonder if perhaps we should be starting to think about `this` in
similar terms.

------
jqm
I liked this article. Yes, it was a bit repetitive and had lots of examples.
Which is why I like it.

------
john2x
Here's[1] an open-source book dedicated to "this".

[1]: [https://github.com/getify/You-Dont-Know-
JS/tree/master/this%...](https://github.com/getify/You-Dont-Know-
JS/tree/master/this%20%26%20object%20prototypes)

------
hngiszmo
As I'm doing my first serious projects in JS now, I'm thankful for the article
and the simplifying corrections here. Java.this != JS.this

------
namuol
Great reference doc! Grotesquely thorough.

------
robin_carry
Nice article...actually it helps in explaining new colleagues in our team. The
link to examples is also good.

------
chcokr
I'd say that one possible solution is to not use `this` at all. Same goes for
`new` for that matter.

------
dennisbest
In other words, "this" is nuts!

