var arr = [1,2,3,4,5,1,2,3,4,5];
//1.浅拷贝
var arr2 = arr; // 此时arr或者arr2里面的值改变,都会影响另一个数组;
// 深拷贝
// 但是 数组每一项是一个对象只是拷贝对象的地址,新数组改变对象的值,原数组也会改变
var arr3 = arr.slice(0);
var arr4 = arr.concat();
let [...arr6] = arr;
let arr7 = Object.assign([], arr);// (Object.assign只能深拷贝对象,对于数组里面有对象的拷贝也是浅拷贝)
比如:
var arr= [{name:'zs',age:'14'}]
var brr = arr.slice(0)
brr[0].name='ls'
console.log(arr) // [{name:'ls',age:'14'}]
// 真正的拷贝,不会对原来造成影响
var arr5 = JSON.parse(JSON.stringify(arr));
/*
但是有以下问题
1. 他无法实现对函数 、RegExp等特殊对象的克隆
2. 会抛弃对象的constructor,所有的构造函数会指向Object
3. 对象有循环引用,会报错
*/
//js 封装深拷贝(前提里面没有对象)
function copyArray(arr) {
return arr.map(function(item, index, array){
return item;
})
}
// js 封装拷贝并去重
function copyUniqueArray(arr){
return arr.filter(function(item,index,array){
return array.indexOf(item) === index; //indexOf始终返回数组中第一次出现的item位置,与当前index比较,如果就是该位置,则返回
})
}
/**
* 常量
* @type {string}
*/
const TYPE_OBJECT = '[object Object]';
const TYPE_ARRAY = '[object Array]';
/**
* 判断对象的类型
* @param obj 来源对象
* @returns {string} 对象类型
*/
function typeToString(obj) {
return Object.prototype.toString.call(obj)
}
/**
* 深克隆对象
* @param oldObj 源对象
* @returns {Object} 返回克隆后的对象
*/
function deepClone(oldObj) {
let newObj;
if ( oldObj === null ) {
return null
}
if ( typeof oldObj !== 'object') {
return oldObj
}
switch (typeToString(oldObj)) {
case TYPE_OBJECT:
newObj = {}
break;
case TYPE_ARRAY:
newObj = [];
break;
}
for (let i in oldObj) {
newObj[i] = deepClone(oldObj[i]);
}
return newObj
}
// 参考来源[https://juejin.im/post/5ca1e79a51882543b16e2d2c](https://juejin.im/post/5ca1e79a51882543b16e2d2c)