Jump to content

Nasty referencing problems in objects


kael.shipman

Recommended Posts

Hey everyone,

 

I've been having this problem forever and haven't found a fix for it.

 

I'll create an object, then have some function that iterates over an array of elements, attaching an event to each one. The event will contain a reference to a counting variable (it'll be more clear below). However, instead of the function for each object referencing the variable at the time of it's iteration, each function references the variable as it stands at the end of execution of the parent function, meaning that if there are 10 elements in the array, they all end up calling onclickFunction(n), where n = 10 instead of n = 0, n = 1, n = 2, etc....

 

Example:

function myObject() {
    this.elements = [ 'element0', 'element1', 'element2', 'element3' ];
    this.attachEvents();
}

myObject.prototype = {
    constructor : this,

    attachEvents : function() {
        var self = this, i, obj;
        for(i = 0; i < this.elements.length; i++) {
            obj = document.getElementById(this.elements[i]);
            addListener(obj, function() { self.doSomething(i); return; });
        }
    },

    doSomething : function(n) {
        alert(n);
    }
}






//Just for reference....
function addListener(element, type, func, overwrite, bubbling) {
if (typeof element == 'string') element = $(element);
if (!element) return throwError('global::addListener - element not found');

bubbling = bubbling || false;
overwrite = overwrite || false;

if (overwrite) element['on'+type] = '';

if(window.addEventListener) {
	element.addEventListener(type, func, bubbling);
	return true;
} else if(window.attachEvent) {
	element.attachEvent('on' + type, func);
	return true;
}
return throwError('global:addListener - couldn\'t attach event to element');
}

 

Now if I were to create one such object on a page with all the required HTML in place, when I clicked element0, it would alert "4", just as it would when I clicked any of the other elements because it's referencing the variable "i" at the end of execution of the parent function "attachEvents". I know this has to do with closures, but I haven't wrapped my head around those yet. Maybe this is a good place to start.

 

So how do I get it to reference the correct number? It seems to me that there's no way to use variables to do it because you're always setting variables with variables, and at the end, they're all still going to reference a variable that has been incremented since the function was created.

 

The use of addListener() actually leads right into another question I have about transferring ownership, but take a look at my next post for that.

 

Thanks for any help you can offer!

 

-kael

Link to comment
https://forums.phpfreaks.com/topic/79351-nasty-referencing-problems-in-objects/
Share on other sites

Try changing this line:

            addListener(obj, function() { self.doSomething(i); return; });

 

to:

            addListener(obj, function() { var save_i = i; self.doSomething(save_i); return; });

 

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.