首页 > 编程知识 正文

Java浅拷贝和深拷贝的区别,数组浅拷贝和深拷贝的区别

时间:2023-05-06 12:42:45 阅读:32034 作者:2365

前端攻城狮的工作实际应用中,处理数据时往往使用数据的深拷贝和浅拷贝

例如,vue中的数据是双向绑定的,页面显示取决于从后台检索的数据,但如果尝试将此数据作为参数发送到其他接口,则某些字段将是多余的。 在这种情况下,如果删除了原始数据中的字段,页面上的某些数据将不再显示,但如果将多余的数据发送到接口,请求将失败。 在这种情况下,请使用深拷贝和轻拷贝。

深拷贝和浅拷贝可以考察人的能力具体是怎么样的,比如基本功、逻辑能力、编码能力等……。

深拷贝和写拷贝主要针对引用型数据。 因为在分配了基本数据类型后,更改新数据不会影响原始数据。 在参照数据类型分配值后,更改新数据会影响原始数据。 在这种情况下,必须使用深拷贝和写拷贝来定义与原始数据相同但互不影响的数据。

注意:赋值操作和深拷贝的写拷贝不是一回事。

分配值

基本型数据的代入

基本数据类型包括number、string、boolean、undefined和null。 这些数据类型相对简单,赋值后两个变量互不影响。

var a=10;

var b=a;

a=20;

控制台. log (a;

控制台. log (b );

此时的b是10。 之所以将a代入b,是因为复制了a空间的值并将其放入了b空间。 改变a只是在改变a空间,不影响b空间。 基本类型赋值

引用类型数据赋值

引用数据类型有Array、Object。 分配相对复杂,分配后的两个变量共享一个数据内存空间,更改其中一个会更改另一个。

vararr=[ 1,2,3 ];

var brr=arr;

ARR.push(4;

控制台. log (arr;

控制台. log (brr;

此时的brr也有4个要素,和arr一模一样。 将arr分配给brr是将存储在arr中的数据空间地址复制并放入brr中,arr和brr共享同一数据空间,因此更改其中一个数据时,另一个地址也会发生变化。 引用数据类型赋值

暗拷贝和轻拷贝的出现是为了解决这个问题。

浅拷贝

浅副本是指将原始数据中的所有数据复制并放置在新的变量空间中。 两个变量不共享一个内存地址。

对象的浅副本

在系统提供的构造函数Object中使用assign方法。

语法:

Object.assign({},原始对象}

//返回到新对象

示例:

var obj={

name:'jwdxy ',

age:12,

gender: '男'

}

varpbj=object.assign (,obj );

控制台. log (obj;

控制台. log (pbj;

此时的pbj是与obj一模一样的对象的浅副本

但是,存储在obj和pbj两个变量中的数据空间地址不同。 示例:

obj.name='清爽的咖啡豆';

obj.age=20;

控制台. log (obj;

控制台. log (pbj;

此时的pbj一点也没有变化。 name键的值仍为“jwdxy”,age键的值仍为12。 因为obj和pbj不共享数据的内存地址。 复制后的地址不同

注意:如果对象中的数据值为引用数据类型,则在创建新对象时,此引用数据类型的地址也会放置在新对象中。

var obj={

name:'jwdxy ',

age:12,

gender: '男人',

wife:{

name: '乐观的月光',

age:11

}

}

varpbj=object.assign (,obj );

obj.wife.gender='女';

控制台. log (obj.wife;

控制台. log (pbj.wife );

此时,与pbj的wife键相对应的对象包含gender键,值为“女”。 如果对象的属性的值是引用类型数据,则浅副本还会复制该引用类型数据的地址。 这意味着新对象不是完全形成的,或者与原始对象有点关联。 这就是浅拷贝。 浅副本的中值为引用类型

数组的浅拷贝

1、阵列系统构建函数原型上的concat方法

vararr=[ 1,2,3 ];

var brr=arr.concat (

ARR.push(4;

con

sole.log(arr);

console.log(brr);

此时的brr跟原来的arr是一模一样的,改变了arr后,brr也是没有发生改变的,因为brr的数据空间是一个新的地址。数组浅拷贝-concat

2、Array系统构造函数运行上的slice方法

var arr = [1,2,3];

var brr = arr.slice();

arr.push(4);

cosnole.log(arr);

cosnole.log(brr);

此时的brr跟原来的arr是一模一样的,改变了arr后,brr也是没有发生改变的,因为brr的数据空间是一个新的地址。数组浅拷贝 - slice

注意:如果数组中的数据有引用类型数据,上面两个方法对于数组的拷贝,会将这个引用类型数据的地址也拷贝出来。

var arr = [1,2,[3,4]];

var brr = arr.concat();

arr[2].push(5);

console.log(arr[2]);

console.log(brr[2]);

此时brr的下标2数据中,也会多出5。数组中有引用类型的浅拷贝

slice也是一样的

var arr = [1,2,[3,4]];

var brr = arr.slice();

arr[2].push(5);

console.log(arr[2]);

console.log(brr[2]);

此时brr的下标2数据中,也会多出5。数组中有引用类型的浅拷贝

这就是浅拷贝,如果数据中都是基本类型数据,就是完全没有联系的两个数据,但是如果数据中引用类型数据,那两个变量还是有一定的联系。

所谓浅拷贝,也就是说,数组或对象中的值如果是基本类型数据,那拷贝后的数据和原数据是完全没有关联,且互不影响的两个数据,如果数组或对象的值是引用类型数据的话,拷贝后的数组或对象中的引用类型的值跟原数据中的引用类型的值,还是存在共享同一地址的现象。

深拷贝

深拷贝,就是不管原数据中值是什么类型的数据,拷贝后的新数据跟原数据是完全没有关联的。

1、利用json数据和json字符串之间的转换

var obj = {

name:"jwdxy",

age:12,

wife:{

name:"乐观的月光",

age:20

}

}

var str = JSON.stringify(obj);

var pbj = JSON.parse(str);

obj.wife.gender = '女';

console.log(obj.wife);

console.log(pbj.wife);

此时pbj的wife数据中没有gender键,不受obj的影响。对象深拷贝

数组深拷贝

var arr = [1,2,[3,4]];

var str = JSON.stringify(arr);

var brr = JSON.parse(str);

arr[2].push(5);

console.log(arr[2]);

console.log(brr[2]);

此时brr下标2的数据没有5,不受arr的影响。数组深拷贝

2、利用递归遍历对象或数组

function clone(source){

var result;

if(Object.prototype.toString.call(source)==='[object Object]'){

result = {};

}else if(Object.prototype.toString.call(source)==='[object Array]'){

result = []

}else{

return;

}

for(var attr in source){

if(Object.prototype.toString.call(source[attr])==='[object Array]' || Object.prototype.toString.call(source[attr])==='[object Object]'){

result[attr] = clone(source[attr])

}else{

result[attr] = source[attr];

}

}

return result;

}

使用:

var arr = [1,2,{

name:"jwdxy",

age:12,

wife:{

name:"乐观的月光",

age:11

}

}];

var res = clone(arr)

res[0] = 5;

console.log(arr[0],res[0]); // 1 5​

res[2].name = '清爽的咖啡豆'

console.log(arr[2].name,res[2].name); // jwdxy 清爽的咖啡豆

调用函数得到的新数据和原来的数据互不影响。利用递归深拷贝

总之,赋值是赋值,拷贝是拷贝。

浅拷贝,当对象或数组中的数据都是基本数据类型的时候,两个数据之间完全是独立的,如果对象或数组中的值是引用类型的时候,里面是引用类型的值,还是会保持共同的内存地址;

深拷贝出来的两个数据是完全独立的。千锋HTML5学院:教你如何在vue中使用国际化​zhuanlan.zhihu.com千锋HTML5学院:axios的请求拦截和vue路由的导航守卫有什么区别​zhuanlan.zhihu.com千锋HTML5学院:redux-thunk的理解​zhuanlan.zhihu.com

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。