While making the changes I described yesterday I ran into a problem where a long chain of (what I expected to be) references didn’t return the results I was expecting. Somewhere in the chain of references something appears to be getting assigned by value.
In order to isolate the chicanery I built up the following test code, which parallels the structure I created when I included the displayGroup
object in a model component, specifically the arrivals component. The displayGroup
object contains an array of displayValue
objects. What I see is that none of the indirections work as expected. If the initial value of a referenced item is changed then the change is not always reflected in the chain of references. I was originally fooled into thinking it was working because I changed the value of randomFred
and then called the setFred
method of the randomObject
, which actually reassigned the value. If I change the value of randomFred
and don’t call the setFred
method then the pass-through doesn’t work.
I would know how to control this in a C-style language but JavaScript doesn’t give the user this type of control. It does things the way it does things, which in this case means that primitive values (like numbers) are passed by value–period. This appears to include primitive values that are properties of objects (or at least closures). The next trick is to find a workaround.
Let me rephrase that. I can think of some ugly workarounds but I’d obviously prefer to find an elegant and efficient one.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
var randomFred = 3; function randomObject() { this.fred; this.setFred = function(fred) { this.fred = fred; } this.getFred = function() { return this.fred; } } jjj = new randomObject; jjj.setFred(randomFred); //expect 3 alert("jjj.getFred: "+jjj.getFred()); randomFred = 6; jjj.setFred(randomFred); //expect 6 alert("jjj.getFred: "+jjj.getFred()); randomFred = 9; //jjj.setFred(randomFred); //expect 9, get 6 alert("jjj.getFred: "+jjj.getFred()); function superObject() { this.superFred = 4; this.superFred1 = 7; this.superRandomObject = new randomObject(); this.superRandomObject.setFred(this.superFred1); this.randomArray = []; this.randomArray[0] = new randomObject(); this.randomArray[0].setFred(randomFred); } var super1 = new superObject; //expect 7 alert("super1.superRandomObject.getFred: "+super1.superRandomObject.getFred()); super1.superRandomObject.setFred(randomFred); //expect 6 alert("super1.superRandomObject.getFred: "+super1.superRandomObject.getFred()); super1.superRandomObject.setFred(super1.superFred); //expect 4 alert("super1.superRandomObject.getFred: "+super1.superRandomObject.getFred()); super1.superFred = 13; //expect 13, get 4 alert("super1.superRandomObject.getFred: "+super1.superRandomObject.getFred()); randomFred = 12; //expect 12, get 6 alert("super1.randomArray[0].getFred(): "+super1.randomArray[0].getFred()); |