Understanding JS Scoping of “this” – a simple jQuery example
February 11, 2013 11:34 am 1 CommentOne of the more common mistakes that web developers made is the scoping of “this”. This would be one of the criteria of understanding that most testers would look at when hiring new developers. This short post will show a simple code snippet showing how to keep the scoping of “this” can be maintained when writing codes in simple closure. I will first present the wrong code and then followed by the correct one.
This is a quick and dirty example. Our objectives are:
- Create a javascript class that will capture an input box’s value onChange.
- Assign a click event to a button to alert/print out the box’s value
- We’ll assume jQuery has been loaded
Our HTML (easy peasy)
1 2 3 4 5 6 7 8 9 |
<html> <head></head> <body> <p>Let's test some closure</p> <p>Please input anything</p> <input type="text" id="testInput" /> <input type="button" id="execute" value="Print value" /> </body> </html> |
The WRONG Javascript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
function ScopeTester() { this.textValue = "Hi All"; //instantiate with a simple text } //a test function that takes a tester id of an element //this will assign an event action when ready, it will simply save the data in our object ScopeTester.prototype.test = function(testerID) { $(document).ready(function() { $('#testInput').change(function() { this.textValue = $(this).val(); }); }); } ScopeTester.prototype.printValue = function() { alert(this.textValue); } var testerObj = new ScopeTester(); testerObj.test(); $('#execute').click(function() { testerObj.printValue(); }); |
When we execute the above javascript, no matter what you put in the input box, the alert will always say “Hi All”. This is because “this” has changed scope within the jQuery event handler portion, the .change(). In order to rectify that we have to save the current reference to the object to another variable. I like to keep it simple and call it “self”.
So let’s have a look at our correction:
The Correct Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
function ScopeTester() { this.textValue = "Hi All"; //instantiate with a simple text } //a test function that takes a tester id of an element //this will assign an event action when ready, it will simply save the data in our object ScopeTester.prototype.test = function(testerID) { var self = this; $(document).ready(function() { $('#testInput').change(function() { self.textValue = $(this).val(); }); }); } ScopeTester.prototype.printValue = function() { alert(this.textValue); } var testerObj = new ScopeTester(); testerObj.test(); $('#execute').click(function() { testerObj.printValue(); }); |
So by simply saving our reference to the object above into self, we not have a working code at minimal for our intention.
This kind of thing is simple, yet easy to forgot. It’s important to understand scoping and closure especially when we are working on bigger javascript projets such as EmberJS.
You can view my example on JS Fiddle: http://jsfiddle.net/rvbd/vyVYk/8/
If you are interested on learning more about lexical scoping, visit this wikipedia page about it.
Stay tuned for more JS examples and Ember Step by Step tutorial. I’m planning to write one on creating a simple shopping list using jQuery + EmberJS + CodeIgniter!
Tags: closure, coding, javascript, jQuery, self, thisCategorised in: Coding, Javascript, jQuery