【问题标题】:Javascript Array Scope IssueJavascript 数组范围问题
【发布时间】:2013-05-18 06:32:56
【问题描述】:

已解决 - 此示例代码有效,因此我将其与我所拥有的非工作代码进行了比较,发现存在差异。

在我的代码中,那个不起作用的代码在声明颜色数组时忘记在它之前添加一个“var”。

m_color = [];
m_color[0] = 255;
m_color[1] = 255;
m_color[2] = 255;
m_color[3] = 255;

代替:

var m_color = [];
m_color[0] = 255;
m_color[1] = 255;
m_color[2] = 255;
m_color[3] = 255;

就是这样。没有产生错误,我猜它把它创建为一个由所有粒子共享的全局数组。

感谢大家的回答。我将使用它们来编写更好的 javascript 代码。

旧问题(不再相关)如下:


我对 javascript 数组范围有一个疯狂的问题。

我有一个类粒子:

function ParticleClass()
{
    var m_color = [];
    m_color[0] = 255;
    m_color[1] = 255;
    m_color[2] = 255;
    m_color[3] = 255;

    var m_red = 255;
    var m_green = 255;
    var m_blue = 255;

    this.SetRandomColorRGB = SetRandomColorRGB;
    this.SetRandomColorArray = SetRandomColorArray;
    this.DrawParticleRGB = DrawParticleRGB;
    this.DrawParticleArray = DrawParticleArray;

    function SetRandomColorRGB()
    {
        m_red = Math.floor( Math.random() * 255 );
        m_green = Math.floor( Math.random() * 255 );
        m_blue = Math.floor( Math.random() * 255 );
    }

    function SetRandomColorArray()
    {
        m_color[0] = Math.floor( Math.random() * 255 );
        m_color[1] = Math.floor( Math.random() * 255 );
        m_color[2] = Math.floor( Math.random() * 255 );
    }

    function DrawParticleRGB( ctx )
    {
        // I draw the particle using m_red, m_green and m_blue.
    }

    function DrawParticleArray( ctx )
    {
        // I draw the particle using m_color[0], m_color[1], m_color[2]
    }
}

然后我创建一个 ParticleClass 粒子数组并绘制它们。

如果我创建一堆粒子并尝试在屏幕上绘制它们,SetRandomColorRGB 和 DrawParticleRGB 效果很好。每个粒子都有不同的颜色。

如果我使用 SetRandomColorArray 和 DrawParticleArray,所有粒子都有相同的颜色。每次创建新粒子时,所有粒子都会更改为 SetRandomColorArray 选择的最后一个颜色。

在我看来,数组共享内存,而其他变量则没有。这是真的?这是 Javascript 的一个怪癖吗?是不是有别的事情发生了?

谢谢。

【问题讨论】:

  • 这不应该发生,我很确定它不会发生。每个粒子应该有一个不同的数组。您能否在 jsfiddle.net 上提供您的代码的工作演示,以便我们确切知道出了什么问题?
  • 你确定它没有抛出任何错误吗? this.DrawParticleRGB = DrawParticleRGB;不应该是this.DrawParticleRGB = DrawParticleWithRGB;
  • SetRandomColorRGB()SetRandomColorArray() 做同样的事情,减去分配的位置。就个人而言,我会在函数内部添加this.m_red 等,但这是一种风格选择。您的问题必须在您的绘图函数中,除非您的代码中有错误(使用某种调试器来捕获任何警告或错误)。
  • 这不是确切的代码。我的代码里面有更多的东西,所以我写了这个简单的版本。这就是函数名称错误的原因。我将尝试获取一个 jsfiddle 示例。

标签: javascript arrays html scope


【解决方案1】:

变量的作用域在函数 ParticleClass() 内。因此,在这个空间中定义的函数中的变量将与其父级共享范围..

这就是为什么有时你会在 Javascript 中看到这种模式 -

var self = this;
$('.someClass').each(function(i) {
   // function is defined as a closure
   // but it shares its scope with its parent so it can see self and access the parent's  
   // pointer to this.
});

为什么不使用原型来定义函数...

例如..

var myClass = function() {
  this.stuff = 1;
}
myClass.prototype.myFunc = function() {
  // Do Something..
  this.stuff += 5;
}

// Then create instances of your class with
var i = new MyClass();

这将为您提供所需的命名空间...

这是一个例子:http://jsfiddle.net/RvCgJ/

【讨论】:

    【解决方案2】:

    code you posted 没有问题,但话虽如此,这样做会让生活变得更加困难;最好正确使用原型:

    function ParticleClass()
    {
        this.m_color = [255, 255, 255, 255];
    
        this.m_red = 255;
        this.m_green = 255;
        this.m_blue = 255;
    }
    
    (function(p) {
    
    p.SetRandomColorRGB = function () {
            this.m_red = Math.floor( Math.random() * 255 );
            this.m_green = Math.floor( Math.random() * 255 );
            this.m_blue = Math.floor( Math.random() * 255 );
    }
    
    p.SetRandomColorArray = function () {
            this.m_color[0] = Math.floor( Math.random() * 255 );
            this.m_color[1] = Math.floor( Math.random() * 255 );
            this.m_color[2] = Math.floor( Math.random() * 255 );
    }
    
    p.DrawParticleRGB = function( ctx ) {
            // I draw the particle using m_red, m_green and m_blue.
    }
    
    p.DrawParticleArray = function( ctx )
    {
            // I draw the particle using m_color[0], m_color[1], m_color[2]
    }
    
    }(ParticleClass.prototype);
    

    【讨论】:

      【解决方案3】:

      这里...这可能有助于解释为什么会发生:

      var data             = {};               // create a  data object 
      data.string          = "hey society";    // Add a string value property
      data.num             = 0;                // Add a integer value property
      data.arr             = [0,1,2];          // Add an array property
      data.date            = new Date();       // Add an object property
      
                           // here is where the fun starts! 
      
      // Create a var for string property
      
      var sString          = data.string;      // sets to "hey society", as expected.. cool
      data.string          = "changed"         // change the value and the compare :
      data.string         == sString           // returns false, the values are different
      
                            // same happens for a number.
      
      // Now lets copy this array
      var oArr             = data.arr;         // (seeing the comment pattern? XD)
      data.arr             .push(3);           // and modify it.
      data.arr            == oArr              // should be false? Nope. returns true.
                                               // arrays are passed by reference.
      
      var oDate            = data.date           // what about objects?       
      data.date            .setHours(0);         // modify the variable and
      oDate.getTime()     == data.date.getTime() // it returns true, too!
      
                            // so, how do we fix the array problem?
      
      // right in front of yer nose
      var oArrFix          = data.arr.splice(0) // get a new array based on 
      data.arr             .push(4)             // an unmodified version of the original
      data.arr            == oArrFix            // false.. huh..
      
                           // How do we use this as a fix
      
      data.arr["changed"] == false;
      
      oArrFix              = ChangeOriginalArray( data.arr );
      
      // When you are expecting an array..
      function ChangeOriginalArray( arr )       // pass as a parameter
      {
          var aArr = arr.splice(0);             // make a copy!
      
          if (aArr["changed"] == false)         // check has same value!
          {
              aArr["newKey"]   = "newVal";      // add a value
      
              arr["changed"]   = true;          // change original value
          }
      
          return aArr;
      }
      
      oArrFix["newKey"]       == data.arr["newKey"] // false
      oArrFix["changed"]      == true               // no, created
      data.arr["changed"]     == oArrFix["changed"] // nah, passed by value, not reference
      

      【讨论】:

        猜你喜欢
        • 2016-04-24
        • 1970-01-01
        • 1970-01-01
        • 2011-11-13
        • 2013-02-25
        • 1970-01-01
        • 2011-04-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多