js中的数组拷贝(浅拷贝,深拷贝)

问题
        今天写代码时需要拷贝一个内容会变化的数组,使用了=赋值,slice(),concat()方法都不行,修改了原数组后拷贝数组也变了,原因是这个数组内容是object,而object是引用类型,需要使用深拷贝,最后使用var newArr = JSON.parse(JSON.stringify(arr));解决

浅拷贝&深拷贝
        浅拷贝:如果数组元素是基本类型,就会拷贝一份,互不影响,而如果是对象或者数组,就会只拷贝对象和数组的引用,无论对新旧数组的哪一个进行了修改,两者都会发生变化。
        深拷贝:完全的拷贝一个对象,即使嵌套了对象,两者也相互分离,修改一个对象的属性,也不会影响另一个。

var arr = [{name: 'wens'},{age: '26'}];           //原数组 
var newArr1 = arr;                                //浅拷贝
var newArr2 = arr.slice();                        //浅拷贝
var newArr3 = arr.concat();                       //浅拷贝
var newArr4 = JSON.parse(JSON.stringify(arr));    //深拷贝
arr[0].name = 'leon';  
arr[1].age = '27';  
console.log(arr);
console.log(newArr1);
console.log(newArr2);
console.log(newArr3);
console.log(newArr4);

运行结果: 

 浅拷贝
1.使用=直接赋值

var newArr = arr;

缺点:由于数组是引用类型,修改了arr或者newArr中的一个会影响全部

2.使用slice()

var newArr = arr.slice();

3.使用concat()

var newArr = arr.concat();

slice()和concat()缺点:当数组内部属性值为引用对象时,使用slice和concat对对象数组的拷贝,整个拷贝还是浅拷贝,拷贝之后数组各个值的指针还是指向相同的存储地址。简单来说就是:

数组中的值如果是引用类型,对其进行增删改,会影响用slice复制的数组,
但是如果数组中的值是基本类型,就不会影响

深拷贝
1.使用JSON.stringify和JSON.parse

不仅可拷贝数组还能拷贝对象(但不能拷贝函数)

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

缺点:JSON.stringify()有一些局限,比如对于RegExp类型和Function类型则无法完全满足,而且不支持有循环引用的对象。

2.深拷贝的一个通用方法

实现思路:拷贝的时候判断属性值的类型,如果是对象,继续递归调用深拷贝函数

var deepCopy = function(obj) {
  // 只拷贝对象
  if (typeof obj !== 'object') return;
  // 根据obj的类型判断是新建一个数组还是一个对象
  var newObj = obj instanceof Array ? [] : {};
  for (var key in obj) {
    // 遍历obj,并且判断是obj的属性才拷贝
    if (obj.hasOwnProperty(key)) {
      // 判断属性值的类型,如果是对象递归调用深拷贝
      newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
   }
}
return newObj;

转自:js中的数组拷贝(浅拷贝,深拷贝)

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值