6 ms·
I'm confused... doesn't that just reduce the question to "what is the current binding of self"?
by jpolitz 14y ago
I'm confused... doesn't that just reduce the question to "what is the current binding of self"?
- jQueryIsAwesome 14y agoAfter 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.