vue对数组进行深拷贝和浅拷贝
浅拷贝
在Vue中,经常需要处理数组类型的数据,使用深复制可以保证数据不被多个组件共享,从而避免数据污染的问题。下面我们将详细讨论Vue中的数组深复制。
首先,我们需要了解深复制和浅复制的区别。浅复制只复制第一层数据,而深复制会递归复制对象中的所有属性。简单的说,浅复制只复制对象的地址,而深复制会创建一个新的对象。
方法一:使用slice()方法
在Vue中,我们通常使用Array.prototype.slice()方法进行浅复制。
这种方法通过调用slice()方法并不传递任何参数来复制数组。它会返回原始数组的一个副本,从而实现数组的复制。这种方法适用于简单的数组复制,但如果数组中包含引用类型的元素,则复制的只是引用,而不是真正的复制。
let arr = [1, 2, [3, 4]];
let copyArr = arr.slice();
arr[0] = 10;
console.log(copyArr[0]); // 1
上述代码中,我们定义了一个包含了嵌套数组的数组arr,并使用了Array.prototype.slice()方法进行了浅复制。然后我们将原数组的第一个元素修改为10,并输出复制数组的第一个元素。由于浅复制只复制了数组的地址,所以修改原数组的元素并没有影响复制数组。
但是,如果我们修改了嵌套数组的元素,就会产生问题。
let arr = [1, 2, [3, 4]];
let copyArr = arr.slice();
arr[2][0] = 10;
console.log(copyArr[2][0]); // 10
上面的代码中,我们将原数组的嵌套数组的第一个元素修改为10,并输出复制数组的嵌套数组的第一个元素。由于浅复制只复制了数组的地址,所以修改原数组的嵌套数组的元素也影响了复制数组。
因此,我们需要使用深复制。
方法二:使用concat()方法
var originalArray = [1, 2, 3];
var copiedArray = [].concat(originalArray);
这种方法通过调用concat()方法并传递原始数组作为参数来复制数组。concat()方法会将原始数组与一个空数组连接起来,从而返回一个新的数组。这种方法与使用slice()方法相似,适用于简单的数组复制。
数组使用数组方法进行深拷贝(concat、slice)只有一级属性为深拷贝,二级属性后就是浅拷贝,如[1,2,3,[1,2,3]]
方法三:使用ES6的展开运算符
var originalArray = [1, 2, 3];
var copiedArray = [...originalArray];
这种方法使用ES6的展开运算符...来复制数组。展开运算符将原始数组的所有元素展开,并创建一个新的数组。这种方法简洁且易于理解,适用于大多数情况。
只有一级属性为深拷贝,二级属性后就是浅拷贝
//需要复制的数组
let arr1 = [{name: "小明", age: 18}, {name: "小芳", age: 20}];
//使用ES6的扩展运算符实现数组深度复制
let arr2 = [...arr1];
方法四:使用Array.from()方法
var originalArray = [1, 2, 3];
var copiedArray = Array.from(originalArray);
这种方法使用Array.from()方法来复制数组。Array.from()方法会将类数组对象或可迭代对象转换为一个新的数组。这种方法适用于复制任何可迭代对象,而不仅仅是数组。
Object.assign(obj1, obj2)
如果目标是对象object:
let obj = {
id: 1,
name: '张三',
age: 10,
}
let newObj = Object.assign({}, obj)
深拷贝
vue.set
Vue提供了一个辅助函数Vue.set()来进行深复制。
let arr = [1, 2, [3, 4]];
let copyArr = Vue.set([], arr);
arr[2][0] = 10;
console.log(copyArr[2][0]); // 3
使用Vue.set()函数,我们可以进行数组的深复制。与浅复制不同,深复制会递归复制所有对象的属性,这样就不会出现数据污染的问题。
JSON.parse(JSON.stringify(obj))
除了Vue.set()函数,我们还可以使用JSON.parse(JSON.stringify())进行深复制。
let arr = [1, 2, [3, 4]];
let copyArr = JSON.parse(JSON.stringify(arr));
arr[2][0] = 10;
console.log(copyArr[2][0]); // 3
JSON.parse(JSON.stringify())方法虽然简单,但需要注意的是它无法复制函数。满足一般使用场景,但无法实现对象中方法(function)的深拷贝
使用Vue提供的观察者模式实现数组深度复制
let arr1 = [{name: "小明", age: 18}, {name: "小芳", age: 20}];
let arr2 = Vue.util.extend([], arr1);
jQuery的extend方法实现深拷贝
var array = [1,2,3,4];
var newArray = $.extend(true,[],array); // true为深拷贝,false为浅拷贝
自行封装深拷贝的函数
function deepClone(obj) {
var target = {};
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
if (typeof obj[key] === 'object') {
target[key] = deepClone(obj[key]);
} else {
target[key] = obj[key];
}
}
}
return target;
}