Hacker News new | ask | show | jobs
by ender7 4209 days ago
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`.
1 comments

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, ...);