ES6复制拷贝数组,对象,json的几种方式总结

2021-06-23 18:05:22 浏览数 (1)

(1)复制数组

数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组。

代码语言:javascript复制
onst a1 = [1, 2];
const a2 = a1;
a2[0] = 2;
a1 // [2, 2]

上面代码中,a2并不是a1的克隆,而是指向同一份数据的另一个指针。修改a2,会直接导致a1的变化。

ES5 只能用变通方法来复制数组。

代码语言:javascript复制
const a1 = [1, 2];
const a2 = a1.concat();
a2[0] = 2;
a1 // [1, 2]

上面代码中,a1会返回原数组的克隆,再修改a2就不会对a1产生影响。

扩展运算符提供了复制数组的简便写法。

代码语言:javascript复制
const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;

上面的两种写法,a2都是a1的克隆。

对象及json数组的拷贝,Object.assign() {…obj} JSON.Parse 等几种拷贝的区别

代码语言:javascript复制
let obj = {
age: 10
}

let obj1 = {
grade: 1,
name: {
first: 'bob'
}
}

let objS = obj1
let objA = Object.assign(obj, obj1)
let objJ = JSON.parse(JSON.stringify(obj1))
let objK = { ...obj1 }

console.log(objA)
console.log(objJ)
console.log(objK)

obj1.grade = 9
obj1.name.first = 'chris'

console.log(objS)
console.log(objA)
console.log(objJ)
console.log(objK)

打印结果:

代码语言:javascript复制
{ age: 10, grade: 1, name: { first: 'bob' } }

{ grade: 1, name: { first: 'bob' } }

{ grade: 1, name: { first: 'bob' } }

{ grade: 9, name: { first: 'chris' } }

{ age: 10, grade: 1, name: { first: 'chris' } }

{ grade: 1, name: { first: 'bob' } }

{ grade: 1, name: { first: 'chris' } }

结论: 由于对象创建在堆上 栈上的变量保存其地址 所以也叫指针变量

浅拷贝 如let simpleObj = obj;

则只拷贝了 obj在栈上的指针变量给 simpleObj 也就是说simpleObj实际存储的值是 obj的对象的内存地址 指向与 obj同样的堆内存地址 所以改变 obj的值 simpleObj 的值也会改变

深拷贝 就是copy了一份对象 放在另一块堆内存地址 改变之前的对象 对这个复制的对象不会有任何影响

js里有几种深拷贝方式

Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。

… 扩展和 assign 一样

JSON.parse(JSON.Stringify()) 深拷贝 但是缺点是不能拷贝 constructor 方法 解决办法就是递归

0 人点赞