javascript - for 循环内 new 运算符时的奇怪行为

标签 javascript

这段代码:

  for(var i = 0; i < count; ++i)
  {
    var coin = new Coin(mStage , { x : 0 , y : 0 });
    coin.id = i;
    mAvailableCoins.push(coin);
  }

行为异常。我尝试观察 mAvailableCoins[0] - [3] 的变量,发现它实际上根本没有被推送。被推送的是 Coin 的单个实例,这是我创建的第一个实例。这在我设置的 ID 中很明显。

当我设置 mAvailableCoins[0] 时,其 id 为 0。接下来将新创建的硬币插入数组,设置 id mAvailableCoins[1].id 为 1。这是预期的。我检查 mAvailableCoins[0],它的 id 也是 1。

我在代码的不同 for 循环上运行它,它在那里工作。它就在这里失败了。这是我的有效示例,尽管它被放置在不同的文件/范围/方法等上。

  var coins = world.borrowCoins(mLength , heightCount);
  var i = 0;

  for(var x = 0; x < mLength; ++x)
  {
    for(var y = 0; y < heightCount; ++y)
    {
      //var coin = coins[i];
      var coin = new Coin(mStage , {x : 0 , y : 0});
      coin.x   = mPosition.x + (x * world.blockSize);
      coin.y   = ChunkGroup.pixelHeight - ((y + 1) * world.blockSize);
      coin.id = i;

      world.addInhabitant(coin);
      mStage.addChild(coin.sprite);

      console.log("Coin id : " + coin.id + " position (" + x + " , " + y + ") pos : " + coin.x + " , " + coin.y); 

      i++;
    }
  }

[编辑] 这是我的 Coin.js,这是 Inhabitant 的子类:

define(["src/Inhabitant"], function(Inhabitant)
{
  console.log("Coin.js loaded");

  return (function(stage)
  {
    var mRunSpeed = 0;
    var id = 0;

    function Coin(stage)
    {
      Inhabitant.call(this, stage, 'coinGold.png');
    }

    Coin.prototype = Object.create(Inhabitant.prototype);

    Coin.prototype.update = function(elapsed)
    {
      Inhabitant.prototype.x -= mRunSpeed * elapsed;
    }

    Object.defineProperty(Coin, 'runSpeed', 
      {
          get : function(){ return mRunSpeed; }
        , set : function(speed){ mRunSpeed = speed; }
      });

    Object.defineProperty(Coin, 'id', 
      {
        get : function(){ return mRunSpeed; }
      , set : function(speed){ mRunSpeed = speed; }
      });

    return Coin;

  })();
});

所以这里是它的父级 Inhabitant.js:

define([], function()
{
  console.log("Inhabitant loaded.");

  var Inhabitant = (function()
    {
      var mStage  = null;
      var mSprite = null;
      var mID     = -1;

      function Inhabitant(stage, resource)
      {
        mStage = stage;
        mSprite = new PIXI.Sprite.fromFrame(resource);
      }

      Inhabitant.prototype =
      {
          get sprite(){ return mSprite; }

        , set position(position){ mSprite.position = position; } , get position(){ return mSprite.position; }
        , get x(){ return mSprite.x; } , get y(){ return mSprite.y; }

        , set x(x){ mSprite.x = x; } 

        , set y(y){ mSprite.y = y; }

        , get id(){ return mID; } , set id(id){ mID = id; }

        , update : update
        , show   : show
      }

      function update(elapsed)
      {
        console.log("Update called from Inhabitant");
      }

      function show(show)
      {
        mSprite.visible = show;
      }

      return Inhabitant;

    })();

  return Inhabitant;
});

这是调用循环的 World.js:

define(["src/Coin", "src/Block" , "src/ChunkGroup", "src/Chunk"] , function(Coin, Block , ChunkGroup, Chunk)
{
  console.log("World loaded.");

  return function(stage , position , viewportSize, screenSize , blockSize)
  {
    var onNewFloor = function(Chunk){};

    var mStage             = stage;
    ...
    var mInhabitants         = [];
    var mAvailableCoins      = [];
    ...

    var mOnBorderlineChangedListener = { newBorderline : 0 };

    ...

    function fillCoins(count)
    {
      for(var i = 0; i < count; ++i)
      {
        var coin4 = new Coin(mStage);
        coin4.id = i;
        mAvailableCoins.push(coin4);
      }

      ...
    }

    function init(segmentCount, segmentLength)
    {
      ...
      showBackground();
      fillRampGroups(100);
      fillCoins(850);

      ...
    }

    return World;
  };

});

这是 World 初始化并调用其方法 World.init(...) 的地方:

define(['src/Coin' , 'src/Runner2', 'src/World' , 'src/Chunk', 'src/ChunkGroup'] , function(Coin, Runner2, World, Chunk, ChunkGroup)
{
  console.log("MainGameScene loaded.");

  return function (renderer , screenSize)
  {
    var blockSize = 70;

    var mStage                     = new PIXI.Container();
    ...

    var mWorld = World(mStage, {x : 0 , y : 530}, {width : screenSize.width , height : screenSize.height} , mScreenSize , blockSize);
    mWorld.runSpeed = 350;
    mWorld.init(21, 7); // make sure that the length is odd number...
    ...

    var MainGameScene = {};

    ...

    return MainGameScene;
  }

});

这真是令人难以置信。我做错了什么?

最佳答案

Coin 类的所有实例都使用(共享)相同的变量:

var mRunSpeed = 0;
var id = 0;

因为它们位于您的 get/set 函数的外部范围内。将您的代码更改为:

Object.defineProperty(Coin, 'id', 
      {
        get : function(){ return this._id; }
      , set : function(id){ this._id = id; }
      });

您应该会看到差异。

关于javascript - for 循环内 new 运算符时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33512836/

相关文章:

javascript - Angular 1.4 并在 JavaScript 中使用 ngAnimate

javascript - Backbone.js 从响应中渲染数据

javascript - 堆栈溢出与 JavaScript 过滤功能

javascript - 有没有办法在 iPad 上查看 localStorage 的内容?

javascript - 为什么es6需要构造函数?

javascript - 如何从 Firefox 扩展覆盖 JavaScript 函数?

javascript - 在 JS 中从 JSON 对象检索数据

javascript - Pager JS 参数和 Knockout

javascript - 我如何重用不同颜色的 react 组件?

javascript - "x"不是构造函数