【问题标题】:Javascript array : problems with array declaration and accessJavascript数组:数组声明和访问问题
【发布时间】:2015-03-24 08:55:43
【问题描述】:

我目前正在做一个小项目,以学习 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 = [];

有人有想法吗?谢谢!

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

按空格键调用 createAmmo()

【问题讨论】:

  • 错误究竟来自哪里?检查代码中对“弹药”的引用。另外,“弹药”是否应该在设计上是全球性的?
  • 只是另一个集团的 x 和 y 位置。看看这个:jsfiddle.net/seabon/c057f1oj

标签: javascript arrays scope declaration


【解决方案1】:

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

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

但是当你使用var ammo = []; 时,它会创建局部变量。在同一范围内声明了方法createAmmo(),但您无法访问它 范围来自createAmmo 的正文。

将其作为参数传递给createAmmo

【讨论】:

  • 感谢您的评论!我用 var a=1;我可以在函数中使用它。我不明白..
【解决方案2】:

考虑一下! 这正是您问题的答案! 使用var 关键字时,不能在同一范围内再次定义它!您不能在同一范围内覆盖它。

JavaScript 范围不是 {...} 内的代码。它涵盖了function xx(){...} 中的所有代码。因此,当您编写ammo=[]a=1ammo[a] 时,JavaScript 会尝试定义另一个具有相同名称的变量,然后成功覆盖全局ammo 数组!这成功了,因为没有 var 关键字。当var 关键字出现时,ammo[1] 是未知的,所以没有定义!请记住,数组索引从 0 开始。

使用 ammo[a] 就好像您尝试访问/分配一个值给一个名为 1 的新对象 ammo 的属性。

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

【讨论】:

  • 我不明白:/
【解决方案3】:

如果你使用 var 关键字来声明一个变量这个变量将在它被声明的范围内是本地的,它不能可以在其他范围内访问,如果你使用这里:

var ammo = [];

您的ammo 变量是本地,它不能在函数内部访问(因为每个函数都有自己的范围),但是当您使用时:

ammo = [];

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

编辑:

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

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

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

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

它会完美运行,试试这个DEMO它会在控制台中记录ammo的所有更改。

【讨论】:

  • 感谢您的回复。您说“您的弹药变量是本地的,无法在函数内部访问”。那么我的变量“var a=1;”呢? ?我可以在函数中使用它
  • 在这种情况下,您可以同时使用 a 和 ammo,因为它们与 createAmmo() 在同一范围内,问题在于 setInterval 指令,请查看我的 EDIT。
  • 它似乎不起作用.. setInterval 是一次性执行的。我给你我的 jsfiddle(按空格键换弹药)。你会看到它有效。但是如果你添加“var”,它就不起作用..jsfiddle.net/seabon/c057f1oj
  • 即使使用 var 也能完美运行,我更新了您的 fiddle
  • 不,当你按空格键时,仍然出现错误:Uncaught ReferenceError: ammo is not defined。谢谢你的帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-20
  • 2013-03-24
相关资源
最近更新 更多