1

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

在我的代码中,那个不起作用的代码在声明颜色数组时忘记在它之前添加一个“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 的一个怪癖吗?有其他事情发生吗?

谢谢。

4

3 回答 3

1

在这里...这可能有助于解释为什么会这样:

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
于 2013-05-23T04:14:35.450 回答
1

您发布的代码没有问题,但话虽如此,这样做会使生活变得更加困难;最好正确使用原型:

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);
于 2013-05-23T03:33:36.360 回答
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/

于 2013-05-23T02:46:43.530 回答