Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.


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.


I see that some people are slowly redefining the word "simple" as applied to programming languages. A 4-point bullet list that still requires knowing about typical caller behavior is hardly "simple".


Actually, it's not about typical caller behavior. When you write a function, what 'this' is is going to depend on how your function is called. If you don't want caller behavior to affect your function, don't use 'this'. If you want to allow callers to choose what object your function should act on using a variety of convenient syntaxes, then write your function to use 'this', but be aware of all the ways a caller might set it.


"Predictable" then.


Exactly. Once you understand underlying concept, `this` is not complicated or weird.

Small addendum to your list: "whatever is left of the dot at call-time" is a nice way to explain "base reference" concept, but be wary of non-trivial constructs:

    (f = thing.someFunction)(); // this references global object
    (function(){return thing.someFunction }())(); // this references global object
    eval('thing.someFunction')(); // this references global object


I agree it's a simple concept.

But it's one of the weirdest thing in javascript, and I'd advise to forgo using 'this' in any situation that doesn't absolutely need it.


So basically most open source JS code out there is completely wrong?


I don't think a project is "wrong" if it is working. Also these a just opinions, but I think it's counterproductive.

I feel it's the same as class systems with inheritance and lots of OO properties implemented. It's not wrong, but it's so much overhead, so easy to shoot one's foot, for so few returns. And there's a class syntax coming to ES6, so I'm clearly in the minority.

For a discussion on the "this" use, there is an interesting talk[0] by D.Crockford on the subject, at about 8 min in (but I'd watch the whole thing). I don't agree with everything he is advising, but I think he has pretty compelling arguments overall.

There's a lot of things in js that are not necessary to write good code, and avoiding them can reduce a lot of the complexity IMO. Some people are OK with complexity and want expressivity, I'd prefer basic and predictable easily behaviours.

[0] https://www.youtube.com/watch?v=PSGEjv3Tqo0&noredirect=1


Suboptimal might be a better word. And it should be no surprise that most open source anything is suboptimal.


Very nice way to word it! But I would add that if you are using strict mode (which you should) then you get "undefined" instead of "Window" in rule 2)


Wow. I don't think this is a particularly hard concept, but that's an excellent way of visualising it and will definitely help when I'm debugging.


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/


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.


The way you've written this code, `this` refers to `o`, as it has been evaluated at the time of execution of `f()` (first case) rather than inside the `setTimeout` callback, at which point it'd be `Window` (second case). So yes.

Basically your code is doing this right now:

    o.f = function(){
        console.log(this); // logs `o`, returns `undefined`
        setTimeout(1000, undefined);
    });
If you did this:

    o.f = function(){
        setTimeout(1000, function(){
            console.log(this);
        });
    };
Then it'd be `Window` as in rule #2.


Your comment inspired me to write a post on References in Javascript :) http://perfectionkills.com/know-thy-reference


This is exactly how I explain what "this" is :)



Thanks for that, it's succinct and useful.


Nice summary.


> The author critically misunderstands the way that `this` gets set...

I don't actually. (I'm the author) I know that the this key word is executed at run time to figure out what this is. It is true there are simpler ways to explain this and this blog post isn't that. I link to such a post at the bottom of my own. These are just some examples. There's also more to that blog post than what everyone is discussing, like returning from a constructor and global this in node.js and accessing this in eval and more. Anyway, I didn't submit this to HN and hadn't intended to. I also didn't intend to sit here tonight and put on a thick skin to deal with all this criticism for something I wrote months ago.


Don't take the criticism too hard. I enjoyed the post. I don't regularly write JavaScript so I found many points helpful. There is potential for pedantry here on HN, so dont take offense. I appreciate the post...


The article was a nice refresher about 'this' subtleties, but it put too much work into contrasting it against Java's this, instead of just laying out the actual JS rules.

To me, 'this' is JS is a lot more self explanatory than this is Java. And your article doesn't make that apparent. In JS this is just another object, like any other object. It follows the exact same scoping rules as every other object.


>In JS this is just another object, like any other object.

You are mistaken, "this" is not an object nor a variable, it's a keyword and behaves differently than variable scope. Consider closures for example.


And the tragic thing about "this" being a magic keyword that looks up a dynamic value in the runtime, instead of a normal lexically scoped variable like it appears, is that 90% of the time "this" is exactly the thing you want a closure to close over, so you have to do ridiculous stuff like "var self = this;".

Even knowing this rule very well and being totally hard core OCO (Obsessive Compulsive ORDER, not Disorder) about the code, I still make "this" mistake ALL THE TIME, so whenever something weird happens, "this" mistakes are the first thing I look for.

"this" is such a terrible design flaw, it bites me even when I'm expecting it.


I'd say I use `this` outside of lexical context at least as much as I do within, and I rely on this's behaviour a lot when developing a DSL.

It enables some rather elegant patterns, actually.


Patterns which could have been just as easily implemented using another more explicit technique for dynamic binding (like simply passing the dynamic parameter to the function as a normal argument) without fucking up the entire language design with invisible implicit magic, and dooming millions of programmers to repeatedly make difficult to detect, subtle mistakes, bugs and security holes.

Please give me one example of using "this" outside of lexical context, that is impossible or tangibly inconvenient to do by some other technique that JavaScript already supports.


Well, you could pass around the object but then you'd have to come up with a new object-literal syntax because `this` won't exist any more, unless you're planning on keeping it around but keeping it lexically scoped, in which case you have to stop using object literals as traits and prototypes.

At that point you might as well just redesign the language from scratch, which maybe you'd appreciate.

Guess I'm just not feeling the hate on this one.


I agree. The fact that you have to write library code defensively to still work depending on how your method's call, or that you have to use an awkward bind to preserve the `this` context of a method is so annoying and error-prone to me.


Even when you remember to perform the awkward bind / Function.prototype.call / Function.prototype.apply / var self = this; you still may already be inside of another context where this is not correctly defined. So then your code LOOKS even more like it will work thanks to the cargo cult magic ceremonies you've performed perfectly, but in the wrong place. It's like going into the bathroom like you're supposed to, but then taking a shit on the floor right next to the toilet, then flushing.


I don't think that's how bind works. Can you give a code example that shows unintuitive behavior? What I'm hearing from you is something like:

    function foo() {
        var bar = function() {
            console.log(this);
        };
        return bar.bind(42);
    }

    foo().call(1337); // prints 42
...which behaves as expected, so I'm not sure what you're getting at?


You don't have to do that, you can tell a function what to use by using 'call' or 'apply'. Some people even use bind, but I think it adds too much line noise.


You don't have to do what? Make mistakes? Of course I don't have to make mistakes, but I do all the time, and so do other people.

You have to REMEMBER that you need to explicitly and inconveniently tell the function which "this" to use, by drilling down into Function.prototype.call/apply, even though it LOOKS like it will simply work like any other variable, which it doesn't.

Please consider that programmers are not perfect, and do not have infinite time or unlimited memory or perfectly focused and undistracted attention, and programming languages are user interfaces for imperfect humans, that should minimize the likelihood of errors, not set traps for less experienced programmers to make obvious mistakes, just so that more experienced programmers can gloat over how much smarter they are for having memorized every detail of the language spec. (-; I'm looking at you, automatically inserted semicolon! ;-)

And my point is that I AM an experienced programmer who has memorized every detail of the JavaScript language spec and uses it all the time, yet I STILL make "this" mistakes AGAIN and AGAIN. While on the other hand, I don't think I've ever made a "self" mistake with Python.


The way I think about it ('this' being like any other object), closures are just supplied a default 'this' object (window, in the case of web), and instead of providing a this argument via the argument list, you can choose it with the apply/call/bind functions.


I like your article and it fits well with my usual methodology of grokking something, namely running a bunch of tiny examples until I see the patterns.


For reference, `this` in Node.js is `exports` in whatever module you're in. It's only `global` in the REPL.


Phrasing like "they this keyword is executed at run time" doesn't exactly help your case...


It helped me immensely when I realized

    obj.method();
is a sugar for

    obj.method.call(obj);
Similarly, this picture helped me understand `bind`:

http://i.stack.imgur.com/StZOr.png

The a-ha moment for JS is when you realize it's a way simpler language than you thought it was.


Yes - the trick with JS is to realize it has this functional core, and every object has an __proto__ property, and then most of its syntax is syntactic sugar over the top of that.

   new method()
is syntactic sugar for something like

   var _tmp = {};
   _tmp.__proto__ = method.prototype;
   _tmp.call(method);




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: