Javascript Closures

lemon-tree

x10 Minion
Community Support
Messages
1,420
Reaction score
46
Points
48
The project I am currently working on in Javascript is based around a Google Maps object. This map has multiple event handlers associated with it and I am having problems understanding how to maintain the variable scope when the handler event is called.
Currently, I am using an assigned variable called 'calledObject', but this is both messy and I know it is not the proper way of doing it.
I have truncated the code for simplicity to the main items:
Code:
[B]var calledObject = null;[/B]

function FC(){
	[B]calledObject = this;[/B]

	this.initialiseMap = function(){
	//Create map code truncated here

	google.maps.event.addListener(map, 'click', function(event){
		[B]calledObject[/B].addVertex(event.latLng.lat(), event.latLng.lng(), 0, false, false);
		//This works but doesn't seem like the right way of doing it
	});

	this.addVertex = function(){
		//Add vertex
	}
}
What I want this to do is maintain the link to the 'this' so that I can call this.addVertex rather then calledObject.addVertex like this:
Code:
function FC(){
	this.initialiseMap = function(){
	//Create map code truncated here

	google.maps.event.addListener(map, 'click', function(event){
		[B]this[/B].addVertex(event.latLng.lat(), event.latLng.lng(), 0, false, false);
		//This does not work, closure is not formed
	});

	this.addVertex = function(){
		//Add vertex
	}
}
Obviously, this does not work as when the click event is called the 'this' has changed from referencing the instance of FC().
Basically, I am unsure as to how to form the closure on the variables within the FC object, so that when the click event is called the 'this' object is pointing to the correct thing. I have been reading multiple tutorials and seem to be getting nowhere.
Any assistance would be greatly appreciated.
 

essellar

Community Advocate
Community Support
Messages
3,295
Reaction score
227
Points
63
You've been doing it more or less right (although it is conventional to use a shorter variable name). Keep in mind that "this" is the frame reference in JavaScript, so the only time it's going to refer to the object is when the object is created (using the constructor function). The rest of the time, it's going to refer to the calling context/frame, so the only way to make a sticky internal reference to the object itself is to assign "this" to a variable during construction. As for the variable name, I've most often seen __self (that's a double underscore). You probably don't want to make it global, though, since you may have more than one instance of the object floating around at any one time.
 

lemon-tree

x10 Minion
Community Support
Messages
1,420
Reaction score
46
Points
48
OK, I think I get what you mean. Trying to form a closure on the current 'this' is impossible unless the 'this' is applied to a separate variable; that does make sense now. Being global isn't an issue as only one instance of these objects will ever exist, but it is still good practice to keep the scope enclosed I suppose. So it could be something more like this:
Code:
function FC(){
	var __self = this;

	this.initialiseMap = function(){
	//Create map code truncated here

	google.maps.event.addListener(map, 'click', function(event){
		__self.addVertex(event.latLng.lat(), event.latLng.lng(), 0, false, false);
	});

	this.addVertex = function(){
		//Add vertex
	}
}
This does appear to work and when I push the creation out to a separate method the closure does appear to be formed.
Thank you.
 
Top