ECMAScript变量的值类型有两种,基本类型和引用类型.

浅拷贝与深拷贝

1.我们来看一段代码:

var a = new Object();
a.value = 1;
b = a;
b.value = 2;
alert(a.value);

输出为2,这是为什么呢。
我们从存储来看:
基本类型一般都是number,string,boolean,null,undefind这些,他们占据的空间是固定的,所以把它们存储在栈中,栈按照后进先出的原则存储数据。
引用类型一般是object,function,array,它们的大小是不固定的,所以不能存储在栈区,而是分配到堆区,堆区是内存中的动态区域,程序运行的时候动态分配给代码和堆栈,虽然这些数据大小不固定,但是地址的大小是固定的,所以我们在栈区存储对象在堆区的地址即可。这个地址即指针。

2.浅拷贝

var a = [{a:1},{b:2},{c:3}]

var b = a;

b[0].a = 4;

则a[0] = {a:4} 这是因为当复制对象中存在对象或数组时,b=a只是得到一个内存地址,不是真正的复制,修改b的同时也会修改a。

3.深拷贝:

数组深拷贝

一维数组深拷贝,我们先来看concat() 函数,concat用于连接两个数据,其操作不会影响到原始数组,其实这也不是真正的深拷贝,只对一维数组有效。

var arr1 = [1,2,3];
var arr2=[];
arr2 = arr2.concat(arr1);
arr2[0] = 0;
console.log(arr1);

对象深拷贝

利用JSON.stringify和JSON.parse,转化为JSON再转换为对象

var obj = {
  name: 'FungLeo',
  sex: 'man',
  old: '18'
}
var obj2 = JSON.parse(JSON.stringify(obj));
obj2.old = '20';
console.log(obj,obj2);

递归拷贝

deepCopy()可以实现对象和数组真正的深拷贝。

function deepCopy(p, c) {
    var c = c || {};
    for (var i in p) {
      if (typeof p[i] === 'object') {
        c[i] = (p[i].constructor === Array) ? [] : {};
        deepCopy(p[i], c[i]);
      } else {
         c[i] = p[i];
      }
    }
    return c;
  }

eg

var Array=[[10,11,12],[20,21,22],[30,31,32]];
var CopyArray = deepCopy(Array,CopyArray);
CopyArray[0][0] = 99;
console.log(CopyArray,Array);

var Obj = { a:1, b: {b1:2} };
var CopyObj = deepCopy(Obj,CopyObj);
CopyObj.b.b1 = 3;
console.log(CopyObj,Obj);