4 ms·
After assignment "self" does not change even if "this" does. var player = { play: function(){ var self = this; setTimeout(
by jQueryIsAwesome 14y ago
After assignment "self" does not change even if "this" does.
var player = {
play: function(){
var self = this;
setTimeout(function(){
console.log(self);
});
}
}
- marcusf 14y agoNo but this is still bound at call time, so `self` will be foo in foo.play() just as this, so that's basically the same thing + a standard variable assignment to get the setTimeout working. 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.
- jQueryIsAwesome 14y agoBind is not supported in IE8 and older versions. You could use the underscore library or another one that haves a cross-browser bind method.
- marcusf 14y agoFor my particular use case, IE8 is not an issue, but sure, a shim is like three lines, and we did use that before (when IE8 was an issue).
- pixie_ 14y agoobject.bind doesn't look very clean compared to using self.
- jQueryIsAwesome 14y agoAnd in JS is really easy to create an abstraction for this issue: 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 });
- pixie_ 14y agoIf you're writing abstractions to avoid bad language features, maybe you shouldn't be using bad language features in the first place.
- marcusf 14y agoThe nice thing about it is that it allows you to break out of nesting hell while still being prototyped... e.g. window.setTimeout(this.foo.bind(this), baz); 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).
- epidemian 14y agoBut you still have to be aware of the semantics of `this`: var play = player.play; play(); "self" will still strangely bind to "window" if not in strict mode.
- jQueryIsAwesome 14y agoOf course, taking the method out of the object will produce a different result. But if you are doing something weird like that you should know what you are doing.
- epidemian 14y agoI don't think it's _that_ weid considering JS is a language where functions are perfectly normal values. Someone unfamiliar with the semantics of "this" in JS might expect that: player[playing ? "play" : "pause"]() (a not-so-weird JS pattern) would be the same as: (playing ? player.play : player.pause)()
- jQueryIsAwesome 14y agoIn what other language you have direct access to methods as first class objects to do an immediate execution of a method returned by an execution container (parenthesis in JS) ? I think most people would write it like this: playing ? player.play() : player.pause()
- epidemian 14y ago> In what other language you have direct access to methods as first class objects to do an immediate execution of a method returned by an execution container (parenthesis in JS) ? 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.