2013-05-23 2 views
1

SOLVED - Этот пример кода работал, поэтому я сравнил его с неработающим мной и обнаружил несоответствие.Javascript Array Scope Issue

В моем коде, который не работал, при объявлении массива цветов я забыл добавить перед ним «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? Что-то еще происходит?

Спасибо.

+1

Этого не должно быть, и я уверен, что этого не происходит. Каждая частица должна иметь другой массив. Предоставляете ли вы рабочую демонстрацию своего кода на http://jsfiddle.net/, чтобы мы могли точно знать, что происходит не так? –

+1

Уверены, что это не ошибка? 'this.DrawParticleRGB = DrawParticleRGB;' не должно быть 'this.DrawParticleRGB = DrawParticleWithRGB;' – PSL

+0

'SetRandomColorRGB()' и 'SetRandomColorArray()' выполняет то же самое, за вычетом местоположения назначения. Лично я бы добавил 'this.m_red' и т. Д. Внутри функций, но это выбор стиля. Ваша проблема должна быть внутри ваших функций рисования, если у вас нет ошибок в вашем коде (используйте какой-то отладчик, чтобы поймать любые предупреждения или ошибки). – BLaZuRE

ответ

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/

1

Там нет никаких проблем с 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); 
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