深克隆和浅克隆

1. 浅克隆

1.1 数组的浅克隆

如果是数组,可以利用数组的一些方法,比如 sliceconcat 方法返回一个新数组的特性来实现拷贝,但假如数组嵌套了对象或者数组的话,使用 concat 方法克隆并不完整。如果数组元素是基本类型,就会拷贝一份,互不影响,而如果是对象或数组,就会只拷贝对象和数组的引用,这样无论在新旧数组进行了修改,两者都会发生变化,把这种复制引用的拷贝方法称为浅拷贝

1.2 浅克隆的实现

const arr = [
    'old', 
    1, 
    true, 
    ['old1', 'old2'], 
    {old: 1}
];
function shallowCopy(obj) {
    if (typeof obj !== 'object')     // 只拷贝对象
        return;
    const newObj = obj instanceof Array ? [] : {}; // 根据obj 的类型判断是新建一个数组还是对象
    for (let key in obj) {    // 遍历obj,并且判断是obj的属性才拷贝
        if (obj.hasOwnProperty(key)) {
            newObj[key] = obj[key];
        }
    }
    return newObj;
}
console.log(arr);
console.log(shallowCopy(arr));

2. 深克隆

深克隆就是指完全的克隆一个对象,修改一个对象的属性,不会影响另一个。

2.1 简单的深度克隆

// 方法:深度拷贝一个元素的具体实现
function deepCopy(obj) {
    if (typeof obj !== 'object') 
        return;
    const newObj = obj instanceof Array ? [] : {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
        }
    }
    return newObj;
}

ES5 的常用的对象克隆的一种方式。注意数组是对象,但是跟对象又有一定区别,所以一开始判断了一些类型,决定 newObj 是对象还是数组。