Hacker News new | comments | show | ask | jobs | submit login

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.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: