浅拷贝、深拷贝

对象 clone 问题

// 问题: 引用值的拷贝/克隆/复制 困惑?
// 两个变量指向了内存中的同一个存储空间
var person1 = {
    name: 'zhang',
    age: 18,
    sex: 'male'
}

var person2 = person1;
person2.name = 'Li';
console.log(person1); // {name: "Li", age: 18, sex: "male"}
console.log(person2); // {name: "Li", age: 18, sex: "male"}

浅拷贝

// 解决问题:浅拷贝-无法拷贝引用数据类型和原型数据
Object.prototype.num = 1;
var person1 = {
    name: 'zhang',
    age: 18,
    sex: 'male',
    son: {
        first: 'Lucy'
    }
}

var person2 = {};
// 浅拷贝
//clone(person1, person2);
var person2 = clone(person1);
person2.name = 'Li';
person2.son.second = 'Ben';
console.log(person1); // {name: "zhang", age: 18, sex: "male", son: {…}}
console.log(person2); // {name: "Li", age: 18, sex: "male", son: {…}}

// 浅拷贝封装
function clone(origin, target) {
    var tar = target || {};
    for(var key in origin) {
        // 排除原型
        if (origin.hasOwnProperty(key)) {
            tar[key] = origin[key];
        }
    }
    return tar;
}

深拷贝

// 解决问题:深拷贝
Object.prototype.num = 1;
var person1 = {
    name: 'zhang',
    age: 18,
    sex: 'male',
    children: {
        first: {
            name: 'zhang2',
            age: 11
        }
    },
    car: ['Benz', 'Mazda']
}

var person2 = {};
// 浅拷贝
//clone(person1, person2);
var person2 = deepClone(person1);
person2.name = 'Li';
person2.children.second = {
    name: 'zhang3',
    age: 12
};
person2.car.push('Byd');
console.log(person1); // {name: "zhang", age: 18, sex: "male", son: {…}}
console.log(person2); // {name: "Li", age: 18, sex: "male", son: {…}}

// 深拷贝封装
function deepClone(origin, target) {
    var target = target || {},
        toStr = Object.prototype.toString,
        arrType = '[object Array]';

    for(var key in origin) {
        // 排除原型
        if (origin.hasOwnProperty(key)) {
            // 判断是否为引用值,要排除 null, 得到:数组 或 对象
            if (typeof(origin[key]) === 'object' && origin[key] !== null) {
                // 判断数组 还是 对象
                // if (toStr.call(origin[key]) === arrType) {
                //     target[key] = [];
                // } else {
                //     target[key] = {};
                // }
                // 三目运算
                toStr.call(origin[key]) === arrType ? target[key] = []
                                                    : target[key] = {};

                // 递归
                deepClone(origin[key], target[key]);
            } else {
                // 原始值
                target[key] = origin[key];
            }
        }
    }
    return target;
}


// 深拷贝2:json实现-无法copy方法 - 会忽略掉函数和 undefined 。
var str = JSON.stringify(person1);
var person2 = JSON.parse(str);