0

I'm working on a code where I must pass a different function to some objects.

In this case, I'm trying to pass a different function for the onchange event. So currently what I got is something like this this:

var ArrayList; //Contains some data to use with ObjectArray format { n: data }
var ObjectArray; //Contains several objects format Array[n] = Object;
for(var key in ArrayList){
    var doFunction = function() {
        Object[key].doSomething(ArrayList[key]);
    }
    Object[key].onchange = doFunction;
}

The problem here I believe is that I'm afraid it will execute the code as it is declared and not with the values of the actual variables.

Is there a way to pass the function with the values as it executes? or will the variables get parsed the way its written?

4
  • In your declaration above, the onchange will trigger the function and not before Commented Jul 24, 2012 at 18:34
  • 1
    But this is also valid: for(var key in ArrayList){ Object[key].onchange = function() { doSomething(ArrayList[key]); } } ---- do watch out for closures Commented Jul 24, 2012 at 18:36
  • By trigger do you meant that it will execute on that moment or per example, that in doFunction there won't be an Object[key] but rather a Object[0]? Commented Jul 24, 2012 at 18:54
  • possible duplicate of Javascript infamous Loop problem? Commented Jul 24, 2012 at 19:54

2 Answers 2

2

It's the classic function in a loop problem. You need to understand how closures work.

Read the "Example 3" part of this answer carefully. The whole How do JavaScript closures work? question, too.

Another example that might help understand intuitively:

var key = 5;

var onchange = function () {
    console.log(key);
};

onchange(); // 5

key = 10; // the loop reassigns the key on each iteration

onchange(); // 10
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot, this helped me understand a little bit. I'm afraid it's not 100% understood, but I know what to avoid now. I'll just need to read all of it slowly.
1

This is how it should be done:

var ArrayList; //Contains some data to use with ObjectArray format { n: data }
var ObjectArray; //Contains several objects format Array[n] = Object;
for(var key in ArrayList)
{
    (function(key)
    {
        var doFunction = function() 
        {
            Object[key].doSomething(ArrayList[key]);
        }
        Object[key].onchange = doFunction;
    }(key))    
}

4 Comments

Would it work differently if I'd remove the Object[key].onchange = doFunction; and return doFunction instead and add Object[key].onchange = (function (key) { ... })(key) ?
You could do it this way - (function(key){Object[key].onchange=Object[key].doSomething(ArrayList[key]);}(key))
Like - Object[key].onchange = (function(key) var do Function = function() { Object[key].doSomething(ArrayList[key]); } return doFunction; }(key));
No, you cannot do it that way inside a loop or otherwise all the objects will be assigned the same value throughout! And returning a value inside the loop will not only breaks off the loop but completely exits you out from that function

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.