Javascript Jems - First class functions
Written by Ian Elliot   
Tuesday, 10 August 2010
Article Index
Javascript Jems - First class functions
Pass by value
Clone functions

Bring in the clones

What about other side of the coin, passing a copy of an object?

Banner

Being able to do this mimics pass by value for objects.

This turns out to be fairly easy – all we need is a clone function. For example, consider the following code:

function myfunc(o)
{
o.x=2;
}
var a = { x: 1, y: 2 };
myfunc(a);
alert(a.x);

The function changes the x field in the a object and the alert prints 2 not 1.

A clone function simply creates an object with all of the properties of an existing object. The simplest clone function is:

function clone(o)
{
var c=new Object();
for(p in o)
{
c[p]=o[p];
}
return c;
}

The for(p in o) iterates through all of the properties of o and the line c[p]=o[p] creates a new p property in c and assigns the property o[p] to it.

Note the use of the selector [p] notation rather than the equivalent dot notation simply because p is a variable.

With the help of the clone function we can now pass a by value/copy:

myfunc(clone(a));
alert(a.x);

Now the value of a.x is unchanged by the function.

Of course there is a flaw in this version of clone in that it only works as long as the properties of the object aren’t themselves objects. If they are, our current clone simply copies the references to them and doesn’t clone them in turn. This is often called a shallow copy.

To make a deep copy you need to call clone on each object property:

function clone(o)
{
var c=new Object();
for (p in o)
{
if (typeof (o[p]== "object"))
{
c[p]=new clone(o[p]);
}
else
{
c[p]=o[p];
}
}
return c;
}

This function returns a deep copy of any object and in this respect is a useful general purpose function. It can be used, for example, to stamp out new copies of an object as an alternative to using new and the rest of the object-oriented machinery. To see the deep copy in action we need a slightly modified test example which uses an object with an object property:

function myfunc(o)
{
o.x.v=2;
}

var b = { v: 1, w: 2 };
var a = { x: b, y: 2 };
myfunc(a);
alert(a.x.v);

Notice that now a is an object with a property x which is itself an object, i.e. b. The function now changes the v property within b and if you run this you will see that v is changed to 2. If you change the function call to:

myfunc(clone(a));

then the function gets  a deep copy of the a object to work with and it doesn’t change v which is displayed as 1.

Function scope

A final thought about functions is that it is very important that you realise and remember that Javascript, unlike most other languages, does not use block scope but function scope.

That is, a local variable is local to the function it is declared in and it is created and destroyed along with the function.  For example:

function myfunc1()
{
var a = 1;
{
var a = 2;
}
alert(a);
}
myfunc1();

If JavaScript supported block scope then the second variable a would be different from the first and would override the first for the duration of the block – i.e. until the end of the closing curly bracket.

However with function scope it doesn’t and both a’s are the same variable. In this case it’s obvious but when variables are declared within loops and if statement it is all too easy to suppose that they are unique when they aren’t.

On the other hand any variables that you do declare within a loop or if block are available for use within the rest of the function.

For example:

function myfunc1()
{
if (1 == 1)
{
var a = 1
}
alert(a);
}
myfunc1();

works perfectly and displays the value 1. This is not how most other languages work.

In Javascript functions are objects and sometimes this can be useful.

Banner


JavaScript Jems - The Inheritance Tax

JavaScript should not be judged as if it was a poor version of the other popular languages - it isn't a Java or a C++ clone. It does things its own way.  In particular, it doesn't do inheritance  [ ... ]



JavaScript Jems - Objects Are Anonymous Singletons

JavaScript should not be judged as if it was a poor version of the other popular languages - it isn't a Java or a C++ clone. It does things its own way.  In particular, every object can be regard [ ... ]


Other Articles

<ASIN:0596517742>

<ASIN:0321572602>

<ASIN:0596806752>

<ASIN:0470684143>

<ASIN:0137054890>

<ASIN:0470526912>



Last Updated ( Thursday, 19 August 2010 )