function outer() {
var outer_this = this;
var inner = function() {
var inner_this = this;
// ...
}
}
http://stackoverflow.com/questions/4886632/what-does-var-tha... has some more details.And btw, the `this` situation with javascript is not that bad :) use bind - either the Ecmascript 5 version or shimmed and you will be fine. Not much drama.
var self = this;
When you need to use `this`, you just end up proxying the problem behind a variable. If you don't understand what `this` is, it's not going to magically start correcting your misunderstanding.The only possible value it might have is when nesting functions if you refer to `self` instead of `this` correctly, but this is the only case when I actually use this pattern, and when I first create a nested function that needs to use the parent's scope. Another option is to just `.bind(this)`.
In any case, I would disagree that one should try to avoid `this`. Instead, one should educate themselves to understand what things in the language they're using mean. And this subject is a great weeder question in Web Engineer position interviews. If a person can't implement `bind`, can't explain `call`/`apply`, what strict mode does, and what the `this` keyword means in most contexts, they probably aren't strong enough in JS. This is one of the most fundamental concepts in JS, it shouldn't be a source of confusion.
Dereferencing things that aren't pointers leads to unexpected results in C. Should we avoid dereferencing any variable in C?
I think of `this` in the same way - it behaves normally if you use it the way it's intended to be used. In other words, don't try to read `this` in a callback without binding it first, and you'll be fine.
Or are there other pitfalls I'm unaware of?
var player = {
play: function(){
var self = this;
setTimeout(function(){
console.log(self);
});
}
}On a sidenote, I'm trying to get away from using self, and do object.bind in all my setTimeouts. To my mind, it leads to much cleaner code.
function wait(o){
return setTimeout(function(){ o.action.call(o.this) },o.delay*1000)
}
To use it like this: wait({
action : function(){ console.log(this) },
delay : 1,
this : this
});Since .bind is essentially currying, you could imaginably do window.setTimeout(this.foo.bind(this, bar), baz) as well, if foo is dependent on bar (timing out a request `bar' or something like that).
var play = player.play;
play();
"self" will still strangely bind to "window" if not in strict mode. player[playing ? "play" : "pause"]()
(a not-so-weird JS pattern) would be the same as: (playing ? player.play : player.pause)()I think most people would write it like this:
playing ? player.play() : player.pause()Not sure if i understand the question. This seems to work in Python:
s = "Hello"
up = True
(s.upper if up else s.lower)()
Not that it's a very pythonic piece of code, but it works, and i would expect many other languages support something similar.Anyway, that's tangential. And i wasn't discussion what "most people would" do either. What i was trying to say is that by aliasing "var self = this" you're not automatically immune to the quirks of "this" in JS.
o.f()
Can be decomposed in Python: func = o.f
func()
JavaScript fails this test, and it's a shame. NodeList.prototype.map = Array.prototype.map
Just one line and now you can do stuff like: document.querySelectorAll("div").map(function(ele){
return ele.id
});I don't know if it's really that bad that JS returns the unbound function when doing `obj.someFunc`, as it is consistent with any other property access: it returns the same thing that was assigned to that key in the object, or at some point in its prototype chain.
The really broken behavior, at least for me, is that when doing `var f = obj.someFunc(); f()`, the "this" gets bound to "window" in the f() call, instead of being null, or better yet raising an error whenever referenced, like an undefined variable.