当for循环中的new运算符时的奇怪行为

时间:2015-11-04 02:43:01

标签: 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 i设置时会发现这一点。

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

我在我的代码的不同循环上运行它,它在那里工作。它就在这里失败了。以下是我的示例,虽然它放在不同的文件/范围/方法等上。

  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,这是居民的子类:

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;
  }

});

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

1 个答案:

答案 0 :(得分:2)

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

var mRunSpeed = 0;
var id = 0;

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

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

你应该看到差异。