Last active
December 15, 2015 05:09
-
-
Save richardTowers/5207061 to your computer and use it in GitHub Desktop.
Quick demo of pitfalls of `this` in JavaScript
This file contains 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
<!doctype html> | |
<html> | |
<head> | |
<title>this</title> | |
</head> | |
<body> | |
<div><a id="broken" href="#">Incorrectly bound click</a></div> | |
<div><a id="working" href="#">Correctly bound click</a></div> | |
<div><a id="working2" href="#">Also correctly bound click</a></div> | |
<script> | |
// At this point `this` refers to `window` | |
var _this = this; | |
var i = 0; | |
this.testFunction = function () { | |
// A simple test function | |
console.log(i++); | |
}; | |
var incorrectBinding = function () { | |
// At the moment `this` refers to `window`, but for how long?? | |
this.testFunction(); | |
}; | |
var correctBinding = function () { | |
// `_this` is a variable captured in this function. It will always refer to the same thing. | |
_this.testFunction(); | |
} | |
// This is only supported in modern browsers. Consider a shim or underscore's implementation. | |
var correctBinding2 = incorrectBinding.bind(this); | |
// Both of these will work, because at the moment `this` is still `window`: | |
incorrectBinding(); | |
// => 0 | |
correctBinding(); | |
// => 1 | |
correctBinding2(); | |
// => 2 | |
// But if our function is called as an event handler, things get weird: | |
var brokenElement = document.getElementById('broken'); | |
// When incorrectBinding() is called `this` will refer to `brokenElement` *not* `window`. | |
brokenElement.onclick = incorrectBinding; | |
// click => Uncaught TypeError: Object http://localhost/Playground/# has no method 'testFunction' | |
// The function that we bound to `_this` will still work though: | |
var workingElement = document.getElementById('working'); | |
workingElement.onclick = correctBinding; | |
var workingElement2 = document.getElementById('working2'); | |
workingElement2.onclick = correctBinding2; | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment