Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 7 of 7
  1. #1
    New to the CF scene
    Join Date
    Jun 2010
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Question How do I use a literal in a function declaration?

    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).



    Code:
        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);
    Last edited by JOEL0903; 06-14-2010 at 03:26 PM.

  • #2
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,292
    Thanks
    10
    Thanked 583 Times in 564 Posts
    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:

    Code:
    //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...
    Last edited by rnd me; 06-15-2010 at 03:01 AM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%

  • #3
    New Coder
    Join Date
    Feb 2010
    Posts
    44
    Thanks
    0
    Thanked 3 Times in 3 Posts
    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

  • #4
    New Coder
    Join Date
    Feb 2010
    Posts
    44
    Thanks
    0
    Thanked 3 Times in 3 Posts
    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:

    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.

  • #5
    New Coder
    Join Date
    Feb 2010
    Posts
    44
    Thanks
    0
    Thanked 3 Times in 3 Posts
    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:

    Code:
    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!

  • #6
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,292
    Thanks
    10
    Thanked 583 Times in 564 Posts
    Quote Originally Posted by Skychan View Post

    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...
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%

  • #7
    New Coder
    Join Date
    Feb 2010
    Posts
    44
    Thanks
    0
    Thanked 3 Times in 3 Posts
    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.


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •