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

I'm not sure I like this guide, because in several places it seems to imply the value of `this` is decided by where you define the function, which is only really true for arrow functions. For regular functions, unless you take control of `this`, it will be decided by the caller.

Best way I can think to describe `this`:

-----

1. Either you decide in advance exactly what you want `this` to be:

- Use `.bind()` on your function and fix the value of `this`

- Create an arrow function and get `this` from the lexical scope

- Alias `let self = this` in your desired scope, and only ever reference `self`

- Create a wrapper function which fixes the value of `this` (essentially, implement `.bind()`)

-----

2. Or `this` will be decided by your caller:

- Your caller will `.bind()` your function with an unknown value of `this`

- Your caller will call `.call()` or `.apply()` with an unknown value of `this`

- Your caller will attach your function to an unknown object, then call `unknownObject.yourFunction()`, setting `this` to `unknownObject`

- Your caller will call your function as a standalone function: `let newFunc = someObj.someFunc` - then call it, setting `this` to `global` or `window`

- Your caller will pass your function as a param to something like `setTimeout` and achieve the same effect, setting `this` to `global` or `window`

-----

Obviously, most of the time if you're going to use `this`, #1 is to be preferred, #2 is to be avoided, so it's imperative to decide in advance what you want `this` to be rather than allowing it to be decided by your caller.

(Unless that's absolutely what you want, and you have a good reason why -- like if you're writing a wrapper function which is agnostic to the value of `this` that's passed)



I always advise against calling your `this` alias `self`, because of https://developer.mozilla.org/en/docs/Web/API/Window/self - ie. if you missed out the `let self = this` line, then `self` will still work but it'll refer to `window`.


Surely this is going a little too far - there are tons of similarly innocuous names that will refer to globals if you forget to declare them. name, top, find, scroll, etc.

The real solution to the problem you're describing is strict mode and an editor that highlights undeclared variables!


You're right, of course, except that the entire design of `this` in Javascript is carefully tuned to make #2 easier and more frequent than #1. And we all gleefully exploit it when writing `[].slice.call(arguments)`.

I think it's an open question whether it was actually a horrifyingly bad design decision, or if it's rather that we're all too dumb to get it.




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

Search: