Javascript数组:数组声明和访问存在问题

Javascript数组:数组声明和访问存在问题,javascript,arrays,scope,declaration,Javascript,Arrays,Scope,Declaration,为了学习Js和OOP,我目前正在做一个小项目。但我有个问题,让我解释一下不同的步骤: 1) 我的构造函数: function Ammo(ammoId,posX,posY){ this.id=ammoId; this.x=posX; this.y=posY; $('body').append('<div class="ammo ammo'+this.id+'"></div>'); } 3) 电话: ammo=[]; var a=1; fun

为了学习Js和OOP,我目前正在做一个小项目。但我有个问题,让我解释一下不同的步骤:

1) 我的构造函数:

function Ammo(ammoId,posX,posY){
    this.id=ammoId;
    this.x=posX;
    this.y=posY;
    $('body').append('<div class="ammo ammo'+this.id+'"></div>');
}
3) 电话:

ammo=[];
var a=1;
function createAmmo(){
    var ammoX=main.x;
    var ammoY=main.y;
    ammo[a] = new Ammo(a, ammoX, ammoY);
    ammo[a].position();
    var animAmmo= setInterval("ammo["+a+"].ammomove()",5);
    a++;
}
createAmmo();
我的程序运行得很好。但当我用以下语法声明数组时:

var ammo = [];
它不起作用,我有一个错误“弹药未定义”,但它起作用:

ammo = [];
有人有主意吗?谢谢

编辑:这是我的JSFIDLE:


按空格键调用createAmmo()

var
关键字定义局部变量。这意味着变量仅在当前范围内可见

使用
ammo=[]时它创建全局变量,可从
createAmmo()
访问该变量

但是当您使用
var ammo=[]时,它创建局部变量。在同一作用域中声明了方法
createAmmo()
,但您无法访问此方法 来自
createAmmo
主体的范围

如果使用var关键字声明变量,则将其作为参数传递到
createAmmo

,此变量将位于声明变量的作用域的局部,并且无法在其他作用域中访问,如果使用:

var ammo = [];
您的
ammo
变量是local,无法在函数内部访问它(因为每个函数都有自己的作用域),但使用时:

ammo = [];
您的
ammo
变量是global,可以在整个应用程序中访问

编辑:

要更正我的答案,在这种情况下,您可以在createAmmo()函数中访问a和ammo,因为它们都在同一范围内,但此处的问题是由以下指令引起的:

var animAmmo= setInterval("ammo["+a+"].ammomove()",5);
它会导致无限循环,并抛出未定义的
ammo
每次,我都试图调试您的代码,我认为这是因为
setInterval()
ammo
解释为一个函数,还请注意,将字符串而不是函数传递给setInterval()是一种反模式如中所述,您可以通过调用
ammo[a].ammove()
来避免这种情况,而不使用如下双引号:

var animAmmo= setInterval(ammo[a].ammomove(),5);
它会工作得很好,试试这个,它会在控制台中记录所有
弹药的变化

考虑一下! 这正是你问题的答案! 使用
var
关键字时,不能在同一范围内再次定义它!不能在同一范围内重写此项

JavaScript作用域不是
{…}
中的代码。它涵盖了函数xx(){…}
中的所有代码。因此,当您编写
ammo=[]
a=1
ammo[a]
时,JavaScript尝试使用相同的名称定义另一个变量,然后成功覆盖全局
ammo
数组!这会成功,因为没有
var
关键字。当
var
关键字存在时,弹药[1]未知,因此未定义!请记住,数组索引从0开始

使用ammo[a]时,它的工作原理就好像您试图访问/为一个新对象的名为
1
的属性赋值一样
ammo


只需将
a=1
更改为
a=0

错误到底来自哪里?检查代码中对“ammo”的引用。此外,“弹药”是否应该是全球性的设计?只是另一个集团的x和y位置。看看这个:谢谢你的回复。您说过“您的ammo变量是本地变量,无法在函数内部访问”。那么我的变量“var a=1;”呢?我可以在函数中使用它在本例中,您可以同时使用a和ammo,因为它们与createAmmo()在同一范围内,问题在于setInterval指令,请查看我的编辑。它似乎不起作用。。setInterval是一次性执行的。我给你我的JSFIDLE(按空格键获取弹药)。你会发现它是有效的。但是如果你加上“var”,它就不起作用了。。即使使用var,它也能完美工作,我更新了你的。不,当你按下空格键时,仍然会出现错误:未捕获引用错误:未定义弹药。谢谢你的帮助:)谢谢你的评论!我使用var a=1;我可以在函数中使用它。我不明白..我不明白:/
var animAmmo= setInterval(ammo[a].ammomove(),5);