数组Array浅拷贝深拷贝方法总结

Array复制方法总结
Array.slice(浅拷贝)for() 、while map、 filter
Array.cancat Array.reduce() Object.assign() Es6
扩展运算符 Es6 Array.from()Es6 JSON.parse(JSON.stringify())

ES5 Array复制方法总结

1.Array.slice(浅拷贝)
slice 方法根据我们指定的start、end的index从原数组中返回一个浅拷贝的数组。

  [1, 2, 3, 4, 5].slice(0, 3);
    // [1, 2, 3]
    // Starts at index 0, stops at index 3

// 当不给定参数时,就返回了原数组的拷贝
slice
同样的,处理对象和数组的时候是引用而不是值复制

2. 遍历复制数组:for() 、while、map、 filter、 reduce

for()循环(浅拷贝) *
考虑到函数式编程变得越来越流行,我认为这种方法可能是最不受欢迎的。
在这里插入图片描述

let numbers = [1, 2, 3];
let numbersCopy = [];
for (let i = 0; i < numbers.length; i++) {
 numbersCopy[i] = numbers[i];
}

在这里插入图片描述
这个方法不能有效的拷贝多维数组。
while()循环(浅拷贝)

numbers = [1, 2, 3];
numbersCopy = [];
i = -1;
while (++i < numbers.length) {
 numbersCopy[i] = numbers[i];
}

在这里插入图片描述
Array.map(浅拷贝)

当我们使用map方法时,需要给出一个callback函数用于处理当前的数组,并返回一个新的数组元素。
在这里插入图片描述
同样的,处理对象和数组的时候是引用而不是值复制。

Array.filter(浅拷贝)

Array.filter方法同样会返回一个新数组,但是并不一定是返回同样长度的,这和我们的过滤条件有关。
在这里插入图片描述
同样的,处理对象和数组的时候是引用而不是值复制。

Array.reduce(浅拷贝)
其实用reduce来拷贝数组并没有展示出它的实际功能,但是我们还是要将其能够拷贝数组的能力说一下的

numbers = [1, 2, 3];
numbersCopy = numbers.reduce((newArray, element) => {
 newArray.push(element);
 return newArray;
}, []);

在这里插入图片描述
reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数,将其结果汇总为单个返回值。

同样的,处理对象和数组的时候是引用而不是值复制。
3、Array.cancat(浅拷贝)

在这里插入图片描述

concat将数组与值或其他数组进行组合。

[1, 2, 3].concat(4); // [1, 2, 3, 4]

如果我们不指定参数或者提供一个空数组作为参数,就可以进行浅拷贝。
在这里插入图片描述

同样的,处理对象和数组的时候是引用而不是值复制。

ES6 方法总结

1. Object.assign() 浅拷贝
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
Object.assign()
2. 扩展运算符(浅拷贝)
在这里插入图片描述
这个方法不能有效的拷贝多维数组。数组/对象值的拷贝是通过引用而不是值复制。
3、Array.from(浅拷贝)

可以将任何可迭代对象转换为数组。给一个数组返回一个浅拷贝。
在这里插入图片描述

同样的,处理对象和数组的时候是引用而不是值复制。

JSON.parse & JSON.stringify(深拷贝)

JSON.stringify将一个对象转成字符串;
JSON.parse将转成的字符串转回对象。

将它们组合起来可以将对象转换成字符串,然后反转这个过程来创建一个全新的数据结构。

nestedNumbers = [[1], [2]];
numbersCopy = JSON.parse(
 JSON.stringify(nestedNumbers)
);
numbersCopy[0].push(300);
console.log(nestedNumbers, numbersCopy);
// [[1], [2]]
// [[1, 300], [2]]

这个可以安全地拷贝深度嵌套的对象/数组
几种特殊情况
1、如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式。而不是时间对象;

var test = {
 name: 'a',
 date: [new Date(1536627600000), new Date(1540047600000)],
};
let = JSON.parse(JSON.stringify(test))

在这里插入图片描述
2、如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象;

const test = {
 name: 'a',
 date: new RegExp('\\w+'),
};
const copyed = JSON.parse(JSON.stringify(test));
test.name = 'test'

在这里插入图片描述
3、如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;

const test = {
 name: 'a',
 date: function hehe() {
 console.log('fff')
 },
};
const copyed = JSON.parse(JSON.stringify(test));
test.name = 'test'
console.error('ddd', test, copyed)

在这里插入图片描述
4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null

5、JSON.stringify()只能序列化对象的可枚举的自有属性
例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;

   function Person(name) {
     this.name = name;
    }
    const liai = new Person('liai');
    const test = {
     name: 'a',
     date: liai,
    };
    const copyed = JSON.parse(JSON.stringify(test));
    test.name = 'test'

在这里插入图片描述
递归通用拷贝函数
递归拷贝函数(深拷贝:数组对象通用)

function deepCopy(obj) {
   if (obj === null || typeof obj !== 'object') {
        return obj;
    }
 
    if (obj instanceof Date) {
        return new Date(obj.getTime());
    }
 
    if (Array.isArray(obj)) {
        return obj.reduce((arr, item, i) => {
            arr[i] = deepCopy(item);
            return arr;
        }, []);
    }
    if (typeof obj === 'object') {
        return Object.keys(obj).reduce((newObj, key) => {
            newObj[key] = deepCopy(obj[key]);
            return newObj;
        }, {});
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值