Javascript数组:声明和访问数组时的问题

3

我目前正在进行一个小项目,以学习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>');
}

2) 原型:

Ammo.prototype.position = function(){
    $('.ammo'+this.id).css({
        'top': this.y+"px",
        'left': this.x+"px"
    });
}

Ammo.prototype.ammomove = function(){
    this.y-=1;
    this.position();
}

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)", 而这个可以工作:

ammo = [];

有人有想法吗?谢谢!

编辑:这是我的JsFiddle:https://jsfiddle.net/seabon/c057f1oj/

按下空格键调用createAmmo()


错误到底来自哪里?检查你的代码中是否有对“ammo”的引用。此外,“ammo”是否应该是全局变量设计的,还是不应该? - TAMTAM
返回另一个块的 x 和 y 位置。请查看:https://jsfiddle.net/seabon/c057f1oj/ - Mr.Smith67
3个回答

0

如果你使用var关键字来声明一个变量,那么这个变量将局限于它被声明的作用域内,并且无法在其他作用域中访问。如果你使用:

var ammo = [];

你的ammo变量是局部的无法在函数内部访问(因为每个函数都有自己的作用域),但当你使用:

ammo = [];

你的ammo变量是全局的可以在整个应用程序中访问

编辑:

为了纠正我的答案,在这种情况下,你可以在createAmmo()函数内部访问a和ammo,因为它们都在同一个作用域内,但问题在于这条指令:

var animAmmo= setInterval("ammo["+a+"].ammomove()",5);

它导致了一个无限循环并且每次都会抛出ammo is not defined,我尝试调试你的代码并且认为这是由于setInterval()ammo解释为函数所导致的,并且请注意将字符串而不是函数传递给setInterval()是一个反模式,在JavaScript 反模式章节中指出,你可以通过像这样不使用双引号来调用ammo[a].ammomove()来避免这种情况:

var animAmmo= setInterval(ammo[a].ammomove(),5);

它将完美地工作,试试这个演示,它会在控制台中记录所有ammo的更改。


谢谢您的回复。您说:“您的弹药变量是局部的,无法在函数内部访问”。那么我的变量“var a=1;”呢?我可以在函数中使用它吗? - Mr.Smith67
在这种情况下,您可以同时使用a和ammo,因为它们在createAmmo()函数的相同作用域中,问题在于setInterval指令,请看我的编辑部分。 - cнŝdk
似乎不起作用了。setInterval只执行一次。我给你我的jsfiddle(按空格键获取弹药)。你会发现它可以工作。但是如果添加“var”,它就无法工作了。https://jsfiddle.net/seabon/c057f1oj/ - Mr.Smith67
是的,你说得对,但是当我从这里 setInterval(ammo[a].ammomove(),5); 中删除双引号 " 时,它就可以工作了,请看这个编辑后的 fiddle - cнŝdk
是的,对于控制台来说没问题,但是使用setInterval却不起作用,而如果去掉“var”,它就能正常工作。 - Mr.Smith67
显示剩余2条评论

0

var 关键字定义了局部变量。这意味着变量仅在当前作用域中可见。

当您使用 ammo = []; 时,它会创建全局变量,可以从 createAmmo() 访问。

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

将其作为参数传递到 createAmmo 中。


谢谢您的评论!我使用了var a=1;,并且我可以在函数中使用它。我不明白... - Mr.Smith67

0
考虑这个问题!这正是你的问题的答案!使用var关键字时,你不能在同一作用域内再次定义它!你不能在同一作用域内覆盖它。JavaScript作用域不仅限于{...}中的代码。它涵盖了function xx(){...}中所有的代码。因此,当你编写ammo=[]a=1以及ammo[a]时,JavaScript尝试定义另一个具有相同名称的变量,然后成功地覆盖全局ammo数组!这是成功的,因为没有var关键字。当出现var关键字时,ammo[1]是未知的,因此它未被定义!记住数组索引从0开始。
使用ammo[a]就像尝试访问/分配一个新对象ammo的名称为1的属性值一样工作。将a=1更改为a=0即可。

我不理解 :/ - Mr.Smith67

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接