【Web前端问题】数组深拷贝和浅拷贝

//深拷贝

var arr1 = [1, 2, 3];

var arr2 = arr1.slice();

arr1.push(4);

console.log(arr2) //[1, 2, 3]

//浅拷贝

var arr1 = [{a:1}];

var arr2 = arr1.slice();

arr1[0].a = 2;

console.log(arr2[0].a) //2

同样的方法,一会是深拷贝一会是浅拷贝,对数组来说,深拷贝和浅拷贝得看数组的格式吗?

回答:

高级语言都是相通的,浅copy指的是arr1, arr身份不同,但是每个项目引用的对象还是同一个,所以当你push的时候,是放到了arr1的地址空间中,而修改{a:1}时,arr1和 arr2都引用了该对象,所以自然就都修改了。

看个python的例子:

a = [1, 2, 3, {'a': 1}]

b = a.copy()

b.append(4)

print(a) # [1, 2, 3, {'a': 1}]

b[3]['a'] = 5

print(a) # 1, 2, 3, {'a': 5}]

print(id(a), id(b)) # 2258595680904 2258597356744 a, b 不同对象

print(id(a[3]), id(b[3])) # 1796950875736 1796950875736 a[3], b[3] 指向同一个字典对象

回答:

用JSON.parse(JSON.stringtify(arr))

回答:

这就要分 基本数据类型和引用数据类型
Number String Boolean NullUndefined属于基本数据类型,基本数据类型是按值访问的,直接等号赋值是值复制
Object Array Function Data等 属于引用数据类型,引用数据类型只能操作对象在栈内存中的引用地址,等号赋值是引用赋值
你第一个 截取的是 1 2 3这三个数字返回数组,因为数字是基本数据类型 所以直接是值复制
第第二个 截取的是 {a:1}这个对象,对象是引用数据类型,复制的是引用地址,使arr1arr2指向同一引用地址,所以更改arr1arr2也会变化

回答:

第一次之所以可以称为深拷贝,是因为里面元素都是基本类型呀,里面有引用类型的数据了就不行了,正常深拷贝你要判断每一个子元素的类型,可以用递归的方法去完成拷贝

回答:

方法1:

var cloneObj = function (obj) {

var str, newobj = obj.constructor === Array ? [] : {};

if (typeof obj !== 'object') {

return;

} else if (window.JSON) {

str = JSON.stringify(obj), //序列化对象

newobj = JSON.parse(str); //还原

} else {

for (var i in obj) {

newobj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i];

}

}

return newobj;

};

方法2:

function deepClone(obj){    

if(!obj&& typeof obj!== 'object'){

return;

}

var newObj= obj.constructor === Array ? [] : {};

for(var key in obj){

if(obj[key]){

if(obj[key] && typeof obj[key] === 'object'){

newObj[key] = obj[key].constructor === Array ? [] : {};

//递归

newObj[key] = deepClone(obj[key]);

}else{

newObj[key] = obj[key];

}

}

}

return newObj;

}

var arr=[{a:1,b:2},{a:3,b:4}]

var newArr=deepClone(arr)

console.log(arr[0])//{a:1,b:2}

newArr[0].a=123

console.log(arr[0])//{a:1,b:2}

还有一个方法就是简单粗暴法!原理很简单,就是先把对象转成字符串,再把字符串转成对象!

var newArr2=JSON.parse(JSON.stringify(arr));

console.log(arr[0])//{a:1,b:2}

newArr2[0].a=123

console.log(arr[0])//{a:1,b:2}

回答:

首先,都是浅拷贝。第一种数据存放基本类型,数组中存放的就是基本类型的值,拷贝的就是基本类型的值,第二种存放的是对象,存放的是对象的地址,拷贝的就是对象的地址。

看一张图吧,你应该就可以明白了。

图片描述

以上是 【Web前端问题】数组深拷贝和浅拷贝 的全部内容, 来源链接: utcz.com/a/143001.html

回到顶部