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看起来你是对的。我想我总算得到了答案