name1 = "Dave";
name2 = name1;
We say that primitive data is copied by value
because the data's literal value is stored in the memory space
allotted to the variable. In contrast, when composite data is copied
to a variable, only a reference to the data (and
not the actual data) is stored in the variable's memory slot.
That reference tells the interpreter where the actual data is kept
(i.e., its address in memory). When a variable that contains
composite data is copied to another variable, it is the
reference (often called a
pointer) and not the data itself that is copied.
Composite data is, hence, said to be copied by
reference.
This makes good design sense because it would be grossly inefficient
to duplicate large arrays and other composite datatypes. But it has
important consequences for our code. When multiple variables are
assigned the same piece of composite data as their value, each
variable does not store a unique copy of the
data (as it would if the data were primitive). Rather, only one copy
of the data exists and all the variables point to it. If the value of
the data changes, all the variables are updated.
Let's see how this affects a practical application. When two
variables refer to the same primitive data, each variable gets its
own copy of the data. Here we assign the value 12 to the variable
x:
var x = 12;
Now let's assign the value of x to a new
variable, y:
var y = x;
As you can guess, y is now equal to 12. But
y has its own copy of the value 12, distinct from
the copy in x. If we change the value of
x, the value of y is
unaffected:
x = 15;
trace(x); // Displays 15 in the Output window
trace(y); // Displays 12 in the Output window
The value of y did not change when
x changed because when we assigned
x to y, y
received its own copy of the number 12 (i.e., the
primitive data contained by
x).
Now let's try the same thing with
composite data. We'll create a new array
with three elements and then assign that array to the variable
x:
var x = ["first element", 234, 18.5];
Now, just as we did before, we'll assign the value of
x to y:
var y = x;
The value of y is now the same as the value of
x. But what is the value of x ?
Remember that because x refers to an array, which
is a composite datum, the value of x is not
literally the array ["first element",
234, 18.5] but merely a
reference to that datum. Hence, when we assign x
to y, what's copied to y
is not the array itself, but the reference contained in
x that points to the array. So both
x and y
point to the same array, stored somewhere in memory.
If we change the array through the variable x,
like this:
x[0] = "1st element";
the change is also reflected in y :
trace(y[0]); // Displays: "1st element"
Similarly, if we modify the array through y, the
change can be seen via x :
y[1] = "second element";
trace (x[1]); // Displays: "second element"
To break the association, use the slice( )
function to create an entirely new array:
var x = ["first element", 234, 18.5];
// Copy each element of x to a new array stored in y
var y = x.slice(0);
y[0] = "hi there";
trace(x[0]); // Displays: "first element" (not "hi there")
trace(y[0]); // Displays: "hi there" (not "first element")
x = 10;
y = 10;
trace(x == y); // Displays: true
Because x and y contain
primitive data, they are compared by value. In a value-based
comparison, data is compared literally. The number 10 in
x is considered equal to the number 10 in
y because the numbers are made up of the same
bytes.
Now, let's assign x and y
identical versions of the same composite data and compare the two
variables again:
x = [10, "hi", 5];
y = [10, "hi", 5];
trace(x == y); // Displays: false
This time, x and y contain
composite data, so they are compared by reference. The arrays we
assigned to x and y have the
same byte values, but the variables x and
y are not equal because they do not store a
reference to the same composite datum. However, watch what happens
when we copy the reference in x to
y:
x = y;
trace(x == y); // Displays: true
Now that the references are the same, the values are considered
equal. Thus, the result of the comparison depends on the references
in the variables, not the actual byte values of the arrays.