在项目中,常常会用到拷贝。es6
浅拷贝和深拷贝,相信你们都知道区别,可是怎么去实现呢?微信
我会分享一些项目中常常会用到的一些方法,而后再手写一个深/浅拷贝的方法。dom
1. Object.assign函数
相信这个不少人都用过,用过就知道,这个在微信端,ie11或更低版本的ie上并不支持。因此咱们就抛弃了这种方法。测试
这种方法也只是浅拷贝,不能知足深拷贝的需求spa
2. 经过es6的扩展运算符...来实现浅拷贝code
let a = { age: 1 } let b = { ...a } a.age = 2 console.log(b.age) // 1
一般,浅拷贝只能解决部分问题。因此咱们来看看深拷贝。对象
3. JSON.parse(JSON.stringify(object))blog
这个方法在项目中用的挺多的。原型链
let a = { age: 1, jobs: { first: 'FE' } } let b = JSON.parse(JSON.stringify(a)) a.jobs.first = 'native' console.log(b.jobs.first) // FE
可是该方法有局限性:
undefined
symbol
本身实现一个深拷贝是很困难的,由于有不少便捷状况须要考虑。好比原型链,dom如何处理。因此我是根据项目实现的一个简易版的深、浅拷贝。
推荐一个库: lodash
var isObject = function(obj) { return obj !== null && (typeof obj === "object" || typeof obj === "function") }; var clone = function(obj, deep) { if (!isObject(obj)) { throw new Error(obj + " is not object"); } var newObj; var cloneArray = function(item) { var newItem = []; var size = item.length; for (var i = 0; i < size; i++) { var vk = item[i]; if (deep && isObject(vk)) { newItem[i] = clone(vk, deep); } else { newItem[i] = vk; } } return newItem; }; var cloneObject = function(item) { var newItem = {}; Object.keys(item).forEach(function(n) { var v = item[n]; if (deep && isObject(v)) { newItem[n] = clone(v, deep); } else { newItem[n] = v; } }); return newItem; }; if (obj instanceof Array) { newObj = cloneArray(obj); return newObj; } newObj = cloneObject(obj); return newObj; }
测试代码:
var obj1 = { a: 1, b: ["a", "b"] }; var obj2 = { b: 2, c: obj1 }; var obj3 = clone(obj2, true); var obj4 = clone(obj2, false); obj1.b = ["a", "b", "c"]; obj1.a = "2"; console.log(obj3); console.log(obj4);
输出结果:
从结果能够看出:
深拷贝obj3的结果不会由于引用类型obj1的改变而改变
浅拷贝obj4的结果会由于引用类型obj1的改变而改变