浅拷贝的实现方式
1. Object.assign()方法
assign()方法是把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。但是他的拷贝方式不是固定的,看下面的代码演示:
let obj = { username: 'kobe' }; let obj2 = Object.assign({},obj); obj2.username = 'xiaoming'; console.log(obj);//{username: "kobe"} |
可以看出,当Object只有一层时,使用assign()方法实现的拷贝是深拷贝。
但是如果Object具有嵌套两层或两层以上的关系时,情况就会有所不同,详情看下面的代码演示:
var obj = { username:"xiaoming", a:{name:"xiaohong", age:36}, }; var obj2 = Object.assign({},obj); obj2.username = "xiaolan"; obj2.a.name = "xiaowang"; console.log(obj.username); // xiaoming console.log(obj.a.name); // xiaowang |
所以可以看出。当使用assign()方法时,如果Object在两层或者两层以上时,就是浅拷贝的形式。
let arr = [1, 3, { username: 'kobe' }]; let arr2=arr.concat(); arr2[2].username = 'wade'; arr2[0] = 0; console.log(arr); // (3) [1, 3, {…}] 0: 1 1: 3 2: {username: 'wade'} |
let arr = [1, 3, { username: ' kobe' }]; let arr3 = arr.slice(); arr3[2].username = 'wade'; arr3[0] = 0; console.log(arr); // (3) [1, 3, {…}] 0: 1 1: 3 2: {username: 'wade'} |
1. 暴力解法,使用递归函数
这种解法的思路就是对一个对象或数组的每一个元素进行遍历,如果元素属于基本数据类型,就直接对其进行拷贝;如果一个元素还是对象或者数组的话,就对该元素进行进一步的遍历。以此类推,直到找到其中的元素属于基本数据类型为止,然后再进行拷贝。实现代码如下:
function deepClone1(obj) { //判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝 var objClone = Array.isArray(obj) ? [] : {}; //进行深拷贝的不能为空,并且是对象或者是 if (obj && typeof obj === "object") { for (key in obj) { if (obj.hasOwnProperty(key)) { if (obj[key] && typeof obj[key] === "object") { objClone[key] = deepClone1(obj[key]); } else { objClone[key] = obj[key]; } } } } return objClone; } |
2. 通过JSON方法实现深拷贝
这就是利用之前提到的JSON的JSON.parse()和JSON.stringify()的两个方法实现。实现代码如下:
let arr = [1, 3, { username: ' kobe' }]; let arr4 = JSON.parse(JSON.stringify(arr)); arr4[2].username = 'xiaoming'; console.log(arr, arr4) |
运行结果如下:
可以看出,两个数组中的username并不相同,所以确实是实现了深拷贝。