This tip is probably old news to some Flash programmers, but for others, it'll hopefully clarify an often misunderstood aspect of OOP. Variables actually work differently, depending on whether you're assigning a primitive data type or an object reference. The difference is subtle, but it can cause confusion when you start passing lots of data between different parts of your code.
There are two kinds of variables: a variable containing a primitive data type (number, boolean, character), or a variable reference to an object in memory (Array, String, Object, etc.). The main difference in behavior occurs during variable assignments. If you create an object and assign it to a variable, the variable only holds a reference to the object in memory, sort of like a pointer to a house on a street. If you assign the same variable to another variable, the object doesn't duplicate itself, it merely passes a reference for the same object to the other variable. Like adding another pointer to the same house on the street. However, assigning a variable containing a primitive data type to another variable will actually clone the value to a new point in memory, like building an identical house on the same street.
Here's an example:
myArray = [1,2,3,4,5];
arrayRef = myArray;
myArray[1] = "Hello";
trace(myArray);
trace(arrayRef);
Ok, so here's what's happening: First, we create an array object in memory (RAM), and set the "myArray" variable as a reference to the array object in memory. When myArray is assigned to the variable arrayRef, it actually passes a reference to the same array object in memory. The next line of code re-defines the second element in myArray with the string value of "Hello". When this element's value changes, tracing out myArray and arrayRef will both output the same value of "1,Hello,3,4,5" because both variables refer to the same array object in memory.
But consider what would happen if we applied the same operations on primitive data types instead of objects:
A = 1;
B = A;
A = 3;
Here, the variable A receives a primitive numeric value of 1. When we assign the value of A to the variable B, B doesn't receive a reference to the same value. Instead, another space in memory (or RAM) is created to hold the number 1, which is then assigned to B. Now we have two variables pointing to two numbers in memory, which is very different from the earlier example, where two variables point to the same object in memory. In the last line of code, A=3, the first slot in your RAM, which contained 1, is now assigned a number 3. When you trace out both variables,
trace(A)
trace(B)
the traceout statements will actually output "1" and "3". References vs. cloning are the main difference in how variables handle objects and primitive data types. When you're debugging, keep in mind the possibility of an object being manipulated somewhere else, with a different variable reference.
Posted by samuel at July 5, 2002 02:21 PMSo, how would one go about cloning an array?
Posted by: michael e. gunn at July 5, 2002 09:11 PMWell, I guess this works, but is there a more simple way to clone an array?:
myArray = [1, 2, 3, 4, 5];
refArray = new Array();
for (var j=0; j<myArray.length; j++) {
refArray[j] = myArray[j];
}
refArray[1]="hello";
trace (myArray);
trace (refArray);
dude, it messed up my code!!!!
line 3 is supposed to be the following:
for (var j=0; j < myArray.length; j++){
Pass an array by value as opposed to a reference:
myArray = [1,2,3,4,5];
arrayRef = myArray.slice();
myArray[1] = "Hello";
Ah hah!
It's kinda funny - I was just reading the article on arrays over at http://www.flashmagazine.com/html/509.htm when I was reminded to check the comments on this page again.
Thanks Guy! I shoulda thought of that, but it skipped my mind...
Posted by: michael e. gunn at July 6, 2002 11:07 AM[QUOTE]the traceout statements will actually output "1" and "3". [/QUOTE]
it will output "3" and "1", won't it?
regards, micha
Posted by: at August 5, 2002 08:09 AMwhat about this ?
ps:u can clone an array using an obj instead of a variable
pippo=new object();
pluto=[];
pluto[1]="1";
pippo=pluto;
delete pluto;
trace(pippo);
trace(pippo[1]);
trace(pluto);
Hi Sam!
I think you made a mistake about the String object:
"a variable reference to an object in memory (Array, String, Object, etc.)"
Even though this might seem utterly confusing:
A = "hey man!";
B = new String("hey man!");
trace(A + " (" + typeof A + ")"); //output -> hey man! (string)
trace(B + " (" + typeof B + ")"); //output -> hey man! (object)
ie a string can be of type string OR of type object depending on how you declare it.
I thought: Wow, maybe you can pass a string by reference if you've declared it as an object. (Not that I'm able to come up some useful code example stright away but I just find those things entertaining.) Anyway, trying this:
C = new String("I am C.");
D = C;
C = new String("I'm not D!");
trace("C: " + C + " (" + typeof C + ")"); //output -> C: I'm not D! (object)
trace("D: " + D + " (" + typeof D + ")"); //output -> D: I am C. (object)
Disappointed! Even if strings are typeof object they're appearantly copied by value in contrast to:
C = new Object();
C.says = "I am C.";
D = C;
C.says = "I'm not D!";
trace("C.says: " + C.says); //output -> C.says: I'm not D!
trace("D.says: " + D.says); //output -> D.says: I'm not D!
where the variable is copied by reference (and D will say whatever C says).
I guess it's just so that strings in AS are primitive datatypes (unlike for example C where I've understood that strings are arrays of datatype char) and the fact that:
B = new String("hey man!");
is typeof object is just a kind of misleading bug. Even with the new FMX2 strict typing:
var B:String = new String("hey man!");
B would be typeof object.
If anyone cared to read all this and have an explanation why typeof acts this way, you're more than welcome to share it with me.
Posted by: Marbled Knee at October 4, 2003 03:09 PMAfter posting the comment above I also noticed that what I mention there holds true even for other primitive datatypes in AS:
E = new Boolean(true);
F = new Number(9);
trace(E + " (" + typeof E + ")"); //output -> true (object)
trace(F + " (" + typeof F + ")"); //output -> 9 (object)
About strings in C: In the comment above it should of course be:
"for example C where I've understood that strings are arrays with elements of datatype char"
Hi, I just wanted so say thank you guys ! i really like your site and i hope you'll continue to improving it.
Posted by: viagra at January 25, 2004 12:06 AM