References Themselves Are Passed by Value

L

lkrubner

Is it true that Javascript has no clone() method, to pass an object by
copy of value instead of reference?

If I have an object and want to make an array out of all of its
instance variables, I can loop through it and pass its values to a new
array, and the class instances will be passed by copy and not by
reference?





Example 9.3: References Themselves Are Passed by Value

// This is another version of the add_to_totals() function. It doesn't
// work, through, because instead of changing the array itself, it
tries to
// change the reference to the array.
function add_to_totals2(totals, x)
{
newtotals = new Array(3);
newtotals[0] = totals[0] + x;
newtotals[1] = totals[1] + x;
newtotals[2] = totals[2] + x;
totals = newtotals; // this line has no effect outside of the
function.
}

Note that this rule applies not only to pass-by-reference, but also
copy-by-reference. You can modify an object through a copy of a
reference, but changing the copied reference itself does not affect the
object nor the original reference to the object. This is a more
intuitive and less confusing case, so we don't illustrate it with an
example.
 
R

Richard Cornford

Is it true that Javascript has no clone() method, to pass
an object by copy of value instead of reference?
Yes.

If I have an object and want to make an array out of all
of its instance variables,

Seems like an odd thing to do.
I can loop through it and pass its values to a new
array, and the class instances will be passed by copy
and not by reference?

If you copy the values from an object's properties you will have a copy
of those values.

If you copy the values from object properties into an Array it is
difficult to see how that Array could be considered a copy of an
instance of a class (assuming we accept the use of the term "class" in a
language that does not have classes).
Example 9.3: References Themselves Are Passed by Value

If this a quote from some source it would be a good idea to make that
obvious (and cite the source) else it reads like a very bizarre
statement on your part.
// This is another version of the add_to_totals() function.
// It doesn't work, through, because instead of changing the
// array itself, it tries to change the reference to the array.

Another example of the inappropriate use of the term "doesn't work" as
the function will do exactly what it has been programmed to do, there
just may be no value it its doing so.
function add_to_totals2(totals, x)
{
newtotals = new Array(3);
newtotals[0] = totals[0] + x;
newtotals[1] = totals[1] + x;
newtotals[2] = totals[2] + x;
totals = newtotals; // this line has no effect outside
// of the function.

It has no effect outside of the function because - totals -, as a formal
parameter, is a named property of the Activation/Variable object for the
current execution context and that object will go out of scope as soon
as the function returns.

On the other hand, a global variable with the name - newtotals - is
either created or has its value assigned by the first line in the
function body. So while this function may have not impact on an array
passed as the first argument to the function call it certainly will have
an effect outside of the function.

By the look of it that global side-effect is an error that sends strong
negative signals when found in a text/example that has an apparent
intent to be instructional.
}

Note that this rule applies not only to pass-by-reference,
but also copy-by-reference.
?

You can modify an object through
a copy of a reference, but changing the copied reference
itself does not affect the object nor the original reference
to the object. This is a more intuitive and less confusing
case, so we don't illustrate it with an example.

This reads like someone is trying to explain the behaviour of javascript
through their own conceptual model. How appropriate that is probably
depends on the level at which the explanation is being pitched, at least
in part. Personally I prefer explanations that mirror the language
specification and, in so far as the conceptual model apparently
presented here differs form the specified behaviour of the language, it
appears to be a source of confusion rather than explanation.

Richard.
 
L

Lasse Reichstein Nielsen

(e-mail address removed) writes:

(I'm going to be exceedingly pedantic, which I find to be necessary
when discussing the finer points of values vs. references :)
Is it true that Javascript has no clone() method, to pass an object by
copy of value instead of reference?

That is correct. One can be created, depending on which properties are
desired of it, but there is no build-in operator or method that
creates a "clone" of an object, for any reasonable meaning of "clone".
If I have an object and want to make an array out of all of its
instance variables,

I assume that "instance variable" means what is usually called
"property" in Javascript? :)
I can loop through it and pass its values to a new
array, and the class instances will be passed by copy and not by
reference?

There are no classes in JavaScript, there are only objects. They
inherit through prototyping instead of class inheritance.

But no, you can't simply create copies of an object. There are
solutions, but you must first decide what a "copy of an object" really
means. Is it a deep or shallow copy, or merely an object with the same
properties but where changes doesn't affect the original object? All
three can be implemented, but in different ways.

Example 9.3: References Themselves Are Passed by Value ....
function add_to_totals2(totals, x) ....
totals = newtotals; // this line has no effect outside of the
function. ....

Note that this rule applies not only to pass-by-reference, but also
copy-by-reference.

If I understand this correctly, then yes. JavaScript is purely
pass-by-value.

Variables cannot contain objects. They can only contain references to
objects. These references are passed and assigned/copied as values.
You can modify an object through a copy of a reference, but changing
the copied reference itself does not affect the object nor the
original reference to the object.

References are immutable values, so you can overwrite variables (or
properties) containing them, but you can't change them. You can also
dereference them to gain access to properties of the object they
are referencing.
This is a more intuitive and less confusing case, so we don't
illustrate it with an example.

Aha. :)

/L
 
L

lkrubner

Sorry I was unclear. I'd tried to look up info on the issue before I
posted here, and I posted the article that was causing me confusion.

In Photoshop I can get what seems like an array of all the paths in an
image by using the pathItems() method. But I can't use methods like
slice() on what I get, because pathItems returns an object, not an
array. I'd like an array of all the paths so I can loop through them
and delete all but one. However, I can't use the pathItems() object
because the number of items would actually change as I looped through
them. I couldn't do a normal for() loop. Not if I have an object
holding the actual paths. But if I had a copy, an array, then I could
loop through that and the array.length property wouldn't change as I
went through the loop. You see? I need a copy, I can't work with direct
references to the paths that I'm deleting.
 
R

RobG

Sorry I was unclear. I'd tried to look up info on the issue before I
posted here, and I posted the article that was causing me confusion.

In Photoshop I can get what seems like an array of all the paths in an
image by using the pathItems() method. But I can't use methods like
slice() on what I get, because pathItems returns an object, not an
array.

To see all the properties of your pathItmes object:

function showProperties(obj){
var msg=[];
for ( prop in obj ){
msg.push(obj[prop]);
}
alert(msg.join('\n'));
}

and call it with:

showProperties(pathItems);
I'd like an array of all the paths so I can loop through them
and delete all but one. However, I can't use the pathItems() object
because the number of items would actually change as I looped through
them. I couldn't do a normal for() loop. Not if I have an object
holding the actual paths.

Using the above script as a starting point, test the value returned by
obj[path] inside the for loop. If you want to delete it, set its
value to undefined - that will remove it.
But if I had a copy, an array, then I could
loop through that and the array.length property wouldn't change as I
went through the loop. You see? I need a copy, I can't work with direct
references to the paths that I'm deleting.

Here's another example:

<script type="text/javascript">
var pathItems = [];
pathItems[0] = 'Path 0';
pathItems[1] = 'Path 1';
pathItems[2] = 'Path 2';
pathItems.sayHi = function(){alert('Hi from pathItems')};

function showProperties(obj){
var msg=[];
for ( path in obj ){
msg.push(obj[path]);
}
alert(msg.join('\n'));
}

function keepPath(obj,keeperPath){
for ( path in obj ){
if (keeperPath != obj[path]){
obj[path] = undefined;
}
}
}

alert('About to show pathItems properties');

// Show pathItems
showProperties(pathItems);

// Call the sayHi method
pathItems.sayHi();

alert('About to remove the sayHi method');

// Remove the sayHi method
pathItems.sayHi = undefined;

// Show modified sayHi
showProperties(pathItems);

alert('About to remove all but \'Path 1\'');

// Remove all but 'Path 01'
keepPath(pathItems, 'Path 1');

// Show modified sayHi
showProperties(pathItems);

</script>
 
T

Thomas 'PointedEars' Lahn

In Photoshop I can get what seems like an array of all the paths in an
image by using the pathItems() method. But I can't use methods like
slice() on what I get, because pathItems returns an object, not an
array.

Arrays are Array objects in JS, i.e. objects having Array() as constructor.


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top