JS浅拷贝与深拷贝只针对的是数组(Array)和对象(Object)两种引用数据类型。引用类型的数据在内存中分两部分存储,分别是存储在栈中的引用地址和存储在堆中的数据。
浅拷贝其实拷贝的是引用类型数据的地址,两个对象共享堆中的数据,一个对象改变了某个属性值,另一个对象的属性值也会跟着改变。而深拷贝则会同时拷贝引用地址和数据,之后两个对象之间是完全独立的,互不影响。
浅拷贝实现方式
//对象的拷贝 var newObj = Object.assign({}, obj); //数组的拷贝 var newArr = arr.concat();或 var newArr = arr.slice();
深拷贝实现方式
1、var newObj = JSON.parse(JSON.stringify(obj));该方式实现简单,但是不能拷贝函数。
2、递归函数
function deepCopy(obj) { if(typeof obj == 'object') { var result = obj.constructor == Array ? [] : {}; for(var i in obj) { if(obj.hasOwnProperty(i)) { // 忽略继承属性 result[i] = typeof obj[i] == 'object' ? deepCopy(obj[i]) : obj[i]; } } return result; }else { var result = obj; return result; } }
注:因为JS并没有对hasOwnProperty属性名进行保护,在obj对象上可能存在同名的属性方法,如下:
var obj = { hasOwnProperty: function() { return false; }, name: 'hello object' };
obj.hasOwnProperty(i)条件语句将始终返回false,这显然不是我们期望的,所以可以使用原型上的hasOwnProperty方法,Object.prototype.hasOwnProperty.call(obj, i);