SitePoint Sponsor

User Tag List

Results 1 to 4 of 4
  1. #1
    SitePoint Member
    Join Date
    Mar 2011
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    variables scope in dynamic functions

    Hi, i have got this piece of code:

    Code:
    var f = [];
    
    var x = 1;
    
    f[0] = function(){alert(x);};
    
    var x = 2;
    
    f[1] = function(){alert(x);};
    
    f[0]();
    f[1]();
    I would like to display the number 1 at first and then 2. but this code produces number 2 for both alerts. I was able to achieve what i wanted with "new" constructor when creating functions but this is not a good practice and after all i am passing these functions as an event handlers and it can't be done with "new" keyword because it is throwing error. I think there are some solutions with arrays e.g the x would be an array of numbers, but i don't like it. Am i missing something important?

    Thanks for your replies.

  2. #2
    Non-Member
    Join Date
    Apr 2004
    Location
    Miami, FL, USA
    Posts
    448
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think this is what you wanna do:
    Code javascript:
    var f = [], x;
    f[0] = function(){alert(x);};
    f[1] = function(){alert(x);};
     
    x = 1;
     
    f[0]();
     
    x = 2;
     
    f[1]();

  3. #3
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,702
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by dehonestator View Post
    I would like to display the number 1 at first and then 2. but this code produces number 2 for both alerts.
    It seems that what you require is for each function to individually retain knowledge of that variable.

    The functions do not know anything about their environment until they are executed. So what you can do is to execute a function, that then returns another function.

    Code javascript:
    var x = 1;
    f[0] = function (x) {
        return function () {
            alert(x);
        };
    }(x);

    By executing the outer function immediately, that outer function has x explicitly assigned as 1. The inner function that's returned, it retains that knowledge. That's called closure, on which you can read up more about at: Javascript Closures

    This is how to achieve what you seem to require.

    Code javascript:
    var f = [];
     
    var x = 1;
    f[0] = function (x) {
        return function () {
            alert(x);
        };
    }(x);
     
    var x = 2
    f[1] = function (x) {
        return function () {
            alert(x);
        };
    }(x);
     
    f[0]();
    f[1]();
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  4. #4
    SitePoint Member
    Join Date
    Mar 2011
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Paul, thank you for your reply. That is exactly what I need. Im going to learn something about the javascript closures. Odd enough i haven't run into that one so far. I have just one question: Do I need to return the inside function? It looks like I'm able to get what I want by this:

    f[0] = function (x)
    {
    alert(x);
    }(x);

    transio, also thank you for your advice but what i need is to remember the parameter value, because the functions i'm creating are passed as an event handler functions and can be called in browser anytime, in random order. So your suggestion works, but expects me to fill the variable 'x', and immediately after that, call the created function. But I do not know when this functions are going to be executed in global scope. I just need to register them to handle some events, remember the values passed to them and then execute on randomly called trigger(user click, mouseover etc.)


Tags for this Thread

Bookmarks

Posting Permissions

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