Tuesday, May 10, 2011

copy arrays & objects in javascript

In javascript, when we assign an array or object to a variable, we are actually making a reference to the objects(array is object too). check this code:

var a = ['henry'];
//b is a reference to a
var b = a;
b[0]   = ['li'];
//we can see a[0] is changed to 'li' as well

In some situations, however, we may just want a copy of the object, instead of a reference.

Let's see how to deal with array first. Copying an array in javascript is surprisingly easy, thanks to the array.slice(start, end) method. The slice() method selects a part of an array, and returns the new array. It accepts two parameters: start, end. If we set start to 0, and omit the end, the method will actually return a copy of the whole array. Check this code snippet:

var a = ['henry'];
//b is a copy of a
var b = a.slice(0);
b[0]   = ['li'];
//we can see a[0] is still 'henry'

When it comes to an object, things are not that easy. javascript doesn't have any method for us to copy an object(one of the things i can't believe).  Fortunately, we can create a prototype method to achieve this goal.

//first, we must know that all javascript objects(function, array, custom objects) are instances of Object.
//and we just create an Object prototype clone method  
Object.prototype.clone = function() {
  //first, it check if this is an array or object
  var cloneObject = (this instanceof Array) ? [] : {};
 //now look through the object's all properties
  for (i in this) {
    //if it is clone, then contiune
    if (i == 'clone') {
    //if the property is also a type of object, recursively call the clone method
    if (this[i] && typeof this[i] == "object") {
        cloneObject[i] = this[i].clone();
    } else {
        //if it is not object type, simply copy it
        cloneObject [i] = this[i]
  return cloneObject;

It is done! Now all javascript objects will have this clone method. Let's see how to use it:

//we create a constructor function

var Person = function (){
    this.name = 'henry';
    this.getName = function(){
        return this.name;
//get a person object
var one = new Person();
//clone this object to two
var two = one.clone();
//now let's change two's name
two.name = 'henry li';
//we can see one's name remain unchanged.

No comments: