一:浅拷贝
var m = { a: 10, b: 20 }var n = m;n.a = 15;//m.a会输出15,因为这是浅拷贝,n和m指向的是同一个堆,对象复制只是复制的对象的引用。实现方式
function simpleClone(initalObj) {
var obj = {}; for ( var i in initalObj) { obj[i] = initalObj[i]; } return obj; }Object.assign()实现
Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目
标对象。但是 Object.assign() 进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身 。 var obj = { a: {a: "hello", b: 21} };var initalObj = Object.assign({}, obj);
initalObj.a.a = "changed";
console.log(obj.a.a); // "changed"
一:深拷贝
var m = { a: 10, b: 20 }
var n = {a:m.a,b:m.b};n.a = 15;这次,我们再来输出m.a ,发现m.a的值还是10,并没有改变,m对象和n对象是虽然所有的值都是
一样的,但是在堆里面,对应的不是同一个了,这个就是深拷贝。实现方式
当object只有一层的时候,是深拷贝var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = Object.assign({}, obj1);obj2.b = 100;console.log(obj1);// { a: 10, b: 20, c: 30 } <-- 沒被改到console.log(obj2);// { a: 10, b: 100, c: 30 }多层时:
var cloneObj = function(obj){ var str, newobj = obj.constructor === Array ? [] : {}; if(typeof obj !== 'object'){ return; } else if(window.JSON){ str = JSON.stringify(obj), //系列化对象 newobj = JSON.parse(str); //还原 } else { for(var i in obj){ newobj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i]; } } return newobj;}; 用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。可以封装如下函数
var cloneObj = function(obj){
var str, newobj = obj.constructor === Array ? [] : {}; if(typeof obj !== 'object'){ return; } else if(window.JSON){ str = JSON.stringify(obj), //系列化对象 newobj = JSON.parse(str); //还原 } else { for(var i in obj){ newobj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i]; } } return newobj;};
递归拷贝
function deepClone(initalObj, finalObj) {
var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况 if(prop === obj) { continue; } if (typeof prop === 'object') { obj[i] = (prop.constructor === Array) ? [] : {}; arguments.callee(prop, obj[i]); } else { obj[i] = prop; } } return obj;}var str = {};var obj = { a: {a: "hello", b: 21} };deepClone(obj, str);console.log(str.a);使用Object.create()方法
直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。
function deepClone(initalObj, finalObj) {
var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况 if(prop === obj) { continue; } if (typeof prop === 'object') { obj[i] = (prop.constructor === Array) ? [] : Object.create(prop); } else { obj[i] = prop; } } return obj;} jquery 有提供一个$.extend可以用来做 Deep Copy。var $ = require('jquery');
var obj1 = { a: 1, b: { f: { g: 1 } }, c: [1, 2, 3]};var obj2 = $.extend(true, {}, obj1);console.log(obj1.b.f === obj2.b.f);// false lodash另外一个很热门的函数库lodash,也有提供_.cloneDeep用来做 Deep Copy。
var _ = require('lodash');
var obj1 = { a: 1, b: { f: { g: 1 } }, c: [1, 2, 3]};var obj2 = _.cloneDeep(obj1);console.log(obj1.b.f === obj2.b.f);// false