...

View Full Version : How do I use a literal in a function declaration?



JOEL0903
06-14-2010, 04:05 PM
I have the following code which attaches a function to events in x number of comboboxes (x will probably always = 4, but I do not want to hard-code this). I wish to pass the value of i to the function being attached as well as the value of tempData. In other words, I want the parameters in function to be the value, not a reference variable.

In the current example, I am using the hard-coded variable ci. This I want to be replaced by a literal created when the event handler is attached (the value of the loop variable i). Also, notice that I get the filter value in the event handler (assigned to the variable ct). I would like to replace this code with the value of tempData which would also be determined when the evenet is attached (it is the same value in this case, but it keeps the onChange event from having to do this each time it runs).





var props = {
col_0: "select",
col_1: "select",
col_2: "select",
col_3: "select",
btn_reset:true,
display_all_text: "-Show All-",
on_filters_loaded: function(o){
//reset all filters
var slcIndexes = o.GetFiltersByType(o.fltTypeSlc, true); //o.fltTypeSlc = 'select'

for(var i=0; i<slcIndexes.length; i++){
//this public method returns a filter DOM element by column index
var slcElm = o.GetFilterElement(slcIndexes[i]);

//tempData = slcElm.options[slcElm.selectedIndex].text;
//window.alert(tempData + " " + slcElm);
tf_AddEvent(slcElm, 'change', onchangeFn=function(){
//ci is the column index for the column to filter on. ct is the new text from the combobox to filter on
var ci;

ci = 2;
var ct = tf_outputTable.GetFilterValue(ci);

tf_outputTable.ClearFilters();
//window.alert("ci= " + ci + " ct= " + ct);
tf_outputTable.SetFilterValue(ci, ct);
tf_outputTable.Filter();
}); //end tf_AddEvent
}
}
}

setFilterGrid("outputTable",props);

rnd me
06-15-2010, 03:57 AM
use a function to act as an variable gate, corralling certain locals into a new scope that is preserved by the functions/events you need.

you simply list the vars to preserve twice: once as formal parameters, once as arguments:



//bad function, no closure on primitives:

for(var i=0; i<4; i++){

setTimeout (function(){ alert(i) }, i * 3210);

}
//shows: 0...1...2...3






//good function, closes named arguments (happens to be same name as the var...)
for(var i=0; i<4; i++)(function(i){

setTimeout (function(){ alert(i) }, i * 3210);

}(i));
// shows: 4...4...4...4
green text added, you change bold part...

Skychan
06-15-2010, 04:29 AM
Well, anonymous functions can access local variables inside the scope that the function was created. So it should work to do the following:

for(var i = 0; i < something; i++)
{
var iCopy = i;
addEvent(function(){
someArray[iCopy];//you should have access to iCopy here
});
}

You would be able to access i as well, only problem is that i will have changed, so by copying the value of i into a variable that isn't accessed by anything else in that scope means that the anonymous function can access it.

If you uncomment tempData you will have access to it inside the anonymous function as well... as long as you add "var" in front of it. I suspect that if you don't have the var in "var tempData...;" that there will only be one variable tempData after the loop and so it will contain the last reference or value that was assigned to it in the last loop. By adding var you ensure that a totally new section of memory is allocated for the reference/value during each loop, and the variable tempData will point to the one created during the appropriate loop for the appropriate anonymous function.

cheers

Skychan
06-15-2010, 04:48 AM
Sry, I should have put my code inside code tags.

rnd_me, there are two problems with your "good function".

First, you are calling the anonymous function during the loop, so you have access to the variable i in order to pass to the function. He is passing the anonymous function as a param to another function, so when the anonymous function is called the var i is not around (so I guess you could pass i to the addEvent() function and it could store it and pass it to the appropriate anonymous function... but that's not good when addEvent() functions are going to accept all kinds of different event handlers).

So here is how your code would be with his code:



for(var i = 0; i < 4; i++)
{
addEvent(function(i){
alert(i);
});//how can the object that handles events know about the variable i?
}


The second problem is quite clear by your output of 4...4...4...4; You are referencing a variable that changes and will have the value 4 in it after the loop ends. He wants each anonymous function to have a variable i that contains the values 0-3, respectively.

Skychan
06-15-2010, 07:14 PM
Woah, I must apologize... I did not realize that JS does not support block-level scoping. Only function level scoping works. So the way to solve your problem is this:



function buildEvents()
{
for(var i = 0; i < 4; i++)
{
var func = function(iCopy){
addEvent(function(){ alert(iCopy); });
};
func(i);
}
}


I tried running the same code that rnd_me wrote, where he defined an anonymous function and ran it immediately after, but that was not correct syntax.. it didn't work. But I tested my above code with addEvents() and runEvents() defined and it totally worked... I got alerts of 0,1,2,3

cheers!

rnd me
06-15-2010, 09:50 PM
The second problem is quite clear by your output of 4...4...4...4; You are referencing a variable that changes and will have the value 4 in it after the loop ends. He wants each anonymous function to have a variable i that contains the values 0-3, respectively.

actually, my example outputs of the two functions are swapped, the function-wrapped code should produce 1...2...3...4.

i thought i fixed it, but i guess i made it worse.

your revised code is essentially the exact same as mine, you just use an intermediate function variable (func), where i use a self-executing function...

Skychan
06-17-2010, 01:55 AM
your revised code is essentially the exact same as mine, you just use an intermediate function variable (func), where i use a self-executing function...

I tried doing my code the same way you did... defining an anonymous function and then running it by putting the brackets and loop variable right after... exact same as yours, but it wouldn't run. It made sense what you were doing even though I've never seen code like that before, but like I said, it didn't work.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum