JavaScript

Deep copy

Let’s use Array to start.
slice(begin, end)
which returns a new array with its elements sliced from [begin] to [end – 1].

var arr = ['one', 'two'];
var arr1 = arr.slice(0);

arr1.concat(arr2)
which returns a new combined array.

var arr1 = arr.concat();

Well does above two fit our requirements perfectly?

var arr = [{a: 1}];
var arr1 = arr.slice();
arr1[0].a = 2;
console.log(arr[0].a);//2

See, using slice() and concat() can duplicate a new array but its inner object is still shallow copy. Using for…in or Object.assign() is also.

How about Object.create()?

var obj = {
    a: [1,2]
};
var obj1 = Object.create(obj);
obj1.a.push(3);
console.log(obj.a);//[1,2,3]

Again fake deep copy. 

Solutions:

1.Consider JSON.parse() and  JSON.stringify() , which help converting JS objects to JSON strings and back.

var arr1 = JSON.parse(JSON.stringify(arr));

This is our first solution. There are still some defects as it cannot work on RegExp or functions. What’s more, it will drop constructor back to Object.

2.Another trick is use $.extend() in jQuery.

var arr1 = $.extend(true, {}, arr);

While this cannot handle inner circular reference.

3.Recursion call plus for…in also realize deep copy.

var src = {
    a: [1,2],
    b: 1,
    c: {
      test: 1
    }
};
var dst = {};
function deepCopy(src, dst) {
  for (var key in src) {    
    if (typeof src[key] === 'object') {
      if (Array.isArray(src[key])) {
          dst[key] = [];
      } else {
          dst[key] = {};
      }    
      deepCopy(src[key], dst[key]);
    } else {
        dst[key] = src[key]; 
    }  
  }
}
deepCopy(src, dst);

Well you can extend this as the case might be.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s