-
-
Save rwaldron/980019 to your computer and use it in GitHub Desktop.
JavaScript: A few ways to work around the lack of `this` propagation in inner functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var name = 'window baby'; | |
var obj = { | |
name: 'object baby', | |
// This is totally broken, because inner functions don't "inherit" the outer | |
// function's `this` value. Instead, their `this` value is the global object. | |
broken: function() { | |
function doStuff() { | |
return this.name + '!?!'; | |
} | |
return doStuff(); | |
}, | |
// You can store a reference to the outer function's `this` value and | |
// reference that variable in the inner function. Super-easy, but it might | |
// feel a little gross. | |
byreference: function() { | |
var that = this; | |
function doStuff() { | |
return that.name + '!!!'; | |
} | |
return doStuff(); | |
}, | |
// You can, of course, also use call invocation to obviate the need for | |
// that extra variable, but if you're going to be doing it a lot, it's going | |
// to get awfully verbose real fast. | |
callinvocation: function() { | |
function doStuff() { | |
return this.name + '!!!'; | |
} | |
return doStuff.call(this); | |
}, | |
// You can also proxy the inner function such that the returned function | |
// is always called with the "correct" `this` value. Of course, if you want | |
// to get `this` dynamically, you're going to either need to store a reference | |
// to the outer function's `this` value in proxy or specify `obj` explicitly. | |
proxy: function(fn) { | |
var context = this; | |
return function() { | |
return fn.apply(context, arguments); | |
}; | |
}, | |
proxying: function() { | |
var doStuff = this.proxy(function() { | |
return this.name + '!!!'; | |
}); | |
return doStuff(); | |
} | |
}; | |
obj.broken() // 'window baby!?!' | |
obj.byreference() // 'object baby!!!' | |
obj.callinvocation() // 'object baby!!!' | |
obj.proxying() // 'object baby!!!' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment