简体   繁体   中英

Javascript: How to modify global variables within functions?

Below is the code I'm working on. I'm wondering why, when I change the variable ttt in the function, the changes do not stay outside of the function? I've declared it as var ttt = new Array; at the very top.

Also, why can't I use the variable i in the function?

code:

  client.on('connection', function()
    {
        var sss;
        var aaa;

            console.log('Connected');

        for (i = 0 ; i < 120 ; i++)
            ttt[i] = 0;

        for (i = 0 ; i < 9 ; i++)
        {
                client.getMatchHistory(434582, function(err, result)        
            {
                sss = JSON.stringify(result);
                var myObject = eval('(' + sss + ')');
                console.log (myObject.object.data[i].object.value);

                ttt[myObject.object.data[i].object.value]++;
            });

        }

            for (i = 0 ; i < 120 ; i++)
                console.log ("Record" + i + " Successes: " + ttt[i]);

    });

As you pointed out, there are two separate problems with your code, and they're both somewhat related. First, ttt is being modified globally. The problem is that you're checking for the modifications before they happen. I suspect that client.getMatchHistory() is making an asynchronous call. There's no guarantee that all the asynchronous operations in the second for loop will be done executing by the time you execute the third for loop, where you read the array.

The second problem is one of scope, but it's not global scope that's your problem. Since client.getMatchHistory() is asynchronous, the callbacks will be called once the loop is done executing. Once the loop's done executing i will have a value of 10 . Likely this is not what you intended. You need to create a callback generating function, that takes the value of i , and returns a function that can be used as a callback. Like this:

function make_callback(i) {
  return function(err, result) {
    // The body of your callback in here
  };
}

And then you should use it like this in the body of the loop:

client.getMatchHistory(434582, make_callback(i))

This will capture the value of i in the current iteration and the generated callback will use that value when executed. That should fix your problem with i .

First of all, all globals variables are effectively 'window' object fields, so you can use window.ttt to be sure you are using global variables instead of local. This code should work, so did you try it in developer tool? what does debugger say about presence of such variable?

As for variable i: sure, you can use it, but it better to use it locally, defining 'var i;' on the top of the function to not spoil global namespace.

The client.getMatchHistory probably asynchronous request, you expect that after loop, you will have filled ttt array, to acheive this you have to make a handler which run after last loop step:

var afterloop=function() {
    for (var i = 0 ; i < 120 ; i++)
       console.log ("Record" + i + " Successes: " + ttt[i]);
}
for (var i = 0 ; i < 120 ; i++)
        ttt[i] = 0;

var i_final=0;
for (var i = 0 ; i < 9 ; i++)
        {   
            var i=i;   //localise i
            client.getMatchHistory(434582, function(err, result)        
            {
                i_final++;
                sss = JSON.stringify(result);
                var myObject = eval('(' + sss + ')');
                console.log (myObject.object.data[i].object.value);

                ttt[myObject.object.data[i].object.value]++;
                if (i_final>8) {afterloop();}
            });

        }

in the sample, i_final counts done requests, they can be done in random order, due to async, so you can't refer to i when deciding to run afterloop() , when i_final count to more than last executed request, you run function that should be executed after last request is done.

Note: please use global vars as less as possible, in your code you used global i without any reason

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM