js数组对象克隆

数组和对象都会有指向问题。

1
2
3
4
5
6
7
8
9
var a = [1,2,3];
var b = [1,2,3];
a==b; //false
//这时a和b都是指向不同的数组,所以a和b不等

var a = [1,2,3];
var b = a;
a==b; //true
//这时a和b都指向同一个数组,所以a和b相等,这里不要理解为a指向数组,b指向a,其实他们都是直接指向数组的。

如果a和b都指向同一个数组或对象,当我们改变其中一个的值时,就会使得另外一个变量的值也跟着变了。

1
2
3
4
var a = [1,2,3];
var b = a;
b.pop();
a; //[1,2]

【注】数组是引用传值,数组的push(),pop(),splice()都会改变修改数组,但是concat()和slice()不会,所以这里说道简单的克隆数组,就可以用这两个方法实现。

关于数组的克隆,我们这里说三个浅克隆的方法:

  1. slice()函数

    1
    2
    3
    4
    var a = [1,2,3];
    var b = a.slice(0);
    b.pop();
    a; //[1,2,3]
  2. concat()函数

    1
    2
    3
    4
    var a = [1,2,3];
    var b = a.concat();
    b.pop();
    a; //[1,2,3]
  3. 最直接的for循环

    1
    2
    3
    4
    5
    6
    7
    var a = [1,2,3];
    var b = [];
    for (var i = 0; i < a.length; i ++) {
    b.push(a[i])
    }
    b.pop();
    a; //[1,2,3]

但是数组里面还有object或是布置一层时,浅克隆就不行了,我们通过浅克隆的方法把数组a赋值给b,这是我们改变数组b第一层的值时,不会影响到a的值,但是改变数组b深一层的值时就会影响到数组a了。这个也很好理解,和单层时是一样的。

那我们如何深层克隆了?

关于这个暂时没什么好方法,最简单直接的就是写个循环,一层一层的浅克隆,从而实现深度克隆。方法参考浅克隆。

【注】object和数组一样存在这样的问题,方法解决类似。