Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript:如何在函数中修改全局变量?_Javascript_Scope_Closures - Fatal编程技术网

Javascript:如何在函数中修改全局变量?

Javascript:如何在函数中修改全局变量?,javascript,scope,closures,Javascript,Scope,Closures,下面是我正在编写的代码。我想知道,为什么当我在函数中更改变量ttt时,更改不会停留在函数之外?我已将其声明为var ttt=new Array在最顶端 另外,为什么我不能在函数中使用变量I 代码: client.on('connection',function()) { var-sss; var aaa; console.log('Connected'); 对于(i=0;i

下面是我正在编写的代码。我想知道,为什么当我在函数中更改变量
ttt
时,更改不会停留在函数之外?我已将其声明为
var ttt=new Array在最顶端

另外,为什么我不能在函数中使用变量
I

代码:

client.on('connection',function())
{
var-sss;
var aaa;
console.log('Connected');
对于(i=0;i<120;i++)
ttt[i]=0;
对于(i=0;i<9;i++)
{
getMatchHistory(434582,函数(err,result)
{
sss=JSON.stringify(结果);
var myObject=eval(“(“+sss+”)”);
console.log(myObject.object.data[i].object.value);

ttt[myObject.object.data[i].object.value]++; }); } 对于(i=0;i<120;i++) console.log(“记录”+i+“成功:+ttt[i]); });
首先,所有全局变量都是有效的“窗口”对象字段,因此可以使用window.ttt来确保使用的是全局变量而不是局部变量。这段代码应该可以工作,所以您是否在开发人员工具中尝试过它?调试器如何解释这种变量的存在


至于变量i:当然,您可以使用它,但最好在本地使用它,定义“var i;”在函数顶部,不要破坏全局名称空间。

客户端.getMatchHistory
可能是异步请求,您希望在循环之后,您将填充
ttt
数组,要实现这一点,您必须在最后一个循环步骤之后运行一个处理程序:

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();}
            });

        }
var afterloop=函数(){
对于(变量i=0;i<120;i++)
console.log(“记录”+i+“成功:+ttt[i]);
}
对于(变量i=0;i<120;i++)
ttt[i]=0;
var i_final=0;
对于(变量i=0;i<9;i++)
{   
var i=i;//本地化i
getMatchHistory(434582,函数(err,result)
{
i_final++;
sss=JSON.stringify(结果);
var myObject=eval(“(“+sss+”)”);
console.log(myObject.object.data[i].object.value);

ttt[myObject.object.data[i].object.value]++; 如果(i_final>8){afterloop();} }); }
在示例中,
i_final
统计已完成的请求,由于异步,它们可以以随机顺序完成,因此在决定运行
afterloop()
时不能参考
i
,当
i_final
计数超过上次执行的请求时,您可以运行上次请求完成后应执行的函数


注意:请尽可能少地使用全局变量,在您的代码中,您毫无理由地使用了全局
i

正如您所指出的,您的代码有两个独立的问题,它们都有一定的相关性。首先,
ttt
正在全局修改。问题是,您正在检查修改是否发生。我怀疑
client.getMatchHistory()
正在进行异步调用。无法保证第二个
for
循环中的所有异步操作都将在执行第三个
for
循环(即读取数组)时完成

第二个问题是范围问题,但问题不在于全局范围。由于
client.getMatchHistory()
是异步的,因此一旦循环执行完毕,就会调用回调。循环完成后,执行
i
的值将为
10
。很可能这不是你想要的。您需要创建一个回调生成函数,该函数接受
i
的值,并返回一个可以用作回调的函数。像这样:

function make_callback(i) {
  return function(err, result) {
    // The body of your callback in here
  };
}
然后你应该在循环体中这样使用它:

client.getMatchHistory(434582, make_callback(i))

这将捕获当前迭代中
i
的值,生成的回调将在执行时使用该值。这应该可以解决你的
i

问题,你能澄清一下你的问题吗?当你说“更改不会停留在函数之外”时,你是什么意思?同样,当你问“为什么我不能在函数中使用变量
I
”时,你是什么意思;此行应更改ttt数组。在函数中。但在函数之外,后面是:console.log(“Record”+i+”成功:“+ttt[i]);无论发生什么情况,仅显示为0。至于我不工作。。。在函数中,console.log中的i(myObject.object.data[i].object.value);始终以未定义和崩溃的形式返回。如果我用一个数字(如0)替换I,它会工作。为什么函数不能从窗口上的(i=0;i<9;i++)引用错误中引用/识别i。我不是在浏览器中运行这个,而是使用Node.js。。。这是个问题吗?那你为什么需要gloval变量呢?添加
var ttt=[]调用函数的地方有一些非常好的响应。谢谢筛选一切。顺便说一句,eicto,你的解决方案奏效了,我只编写了3天的JS,但这确实帮助我了解了更多。并非所有有效的全局变量都是
窗口
对象的属性。在所有其他脚本包含之前使用
var
声明的变量实际上是“全局的”(即:它们可以被随后声明/加载的所有代码访问和修改),但它们绝对不是
窗口
对象的属性。@David SkyMesh这是不正确的。即使您使用
var
声明全局变量,例如
var my_global
,您仍然可以通过
窗口访问它。my_global
@seliopou No您不能。我鼓励你先检查一下。@seliopou看起来你是对的。我想我总算得到了答案