浅拷贝
浅拷贝是对对象或数组进行浅层复制,只复制对象的一层属性,当复制的对象中有引用类型的属性时,复制出来的对象和原对象会共享引用类型的属性。这意味着,如果原对象中的引用类型属性被修改,复制出来的对象也会受到影响。因此,浅拷贝只适用于一些简单的数据类型的对象。
以下是实现浅拷贝的几种方式:
1. Object.assign()
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。返回目标对象。Object.assign() 会覆盖目标对象中与源对象属性名相同的属性值。通过传入一个空对象,可以很容易地实现浅拷贝。
const obj = { a: 1, b: 2 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1, b: 2 }
2. Spread operator
Spread operator 可以将一个对象或数组展开为多个参数,也可以用于浅拷贝。通过展开一个对象,可以将其属性复制到新的对象中。
const obj = { a: 1, b: 2 };
const copy = { ...obj };
console.log(copy); // { a: 1, b: 2 }
3. Array.slice()
Array.slice() 方法返回一个从开始索引到结束索引(不包括结束索引)的新数组。如果不传入任何参数,将返回一个原数组的浅拷贝。可以使用该方法对数组进行浅拷贝。
const arr = [1, 2, 3];
const copy = arr.slice();
console.log(copy); // [1, 2, 3]
4. Array.concat()
Array.concat() 方法用于将一个或多个数组与原数组合并,并返回新的数组。如果不传入任何参数,将返回一个原数组的浅拷贝。可以使用该方法对数组进行浅拷贝。
const arr = [1, 2, 3];
const copy = [].concat(arr);
console.log(copy); // [1, 2, 3]
深拷贝
方式一: 使用JSON.stringify() 和 JSON.parse()
let obj = {
a:NaN,
b: undefined,
c:new Date(),
d:new RegExp(/\d/),
d:new Error(),
e:Infinity
}
let deepObj = JSON.parse(JSON.stringify(obj))
缺陷:
(1)NaN ==> null
(2)undefined ==> 空
(3)时间戳 ==> 字符串时间
(4)错误信息 ==> 空对象
(5)Infinity ==> null
(6)无法实现对象中方法(fountion)的深拷贝
方式二: 使用拓展运算符与Object.assign()
let obj = {
a:NaN,
b: undefined,
c:new Date(),
d:new RegExp(/\d/),
d:new Error(),
e:Infinity
}
let deepObj = JSON.parse(JSON.stringify(obj))
优点:数量较少的时候使用方便、简单,
缺点:只能拷贝外层不能拷贝内层,遇到对象或数组键比较多时,操作不方便
方式三:...解构赋值
let aa = { age: 18, name: 'aaa' }
let bb = {...aa};
bb.age = 22;
console.log(aa.age); // 18
如果只是一层数组或是对象,其元素只是简单类型的元素,那么属于深拷贝(就是一层拷贝,暂时就理解为深拷贝吧!!!!)
方式四: 递归深拷贝是完美的项目中可以自己封装使用
function deepClone( source ) {
if (!isObject(source)) return source; //如果不是对象的话直接返回
if (Array.isArray(source)) {
// 若传入的参数是数组类型, 遍历数组,递归调用
var _arr = []
for(let i=0; i<source.length; i++){
_arr.push(deepClone(source[i])
}
return _arr
} else{
// 若传入的参数是对象类型,遍历对象中的key:value对,递归调用
var _obj = {}
for( var k in source){
_obj[k] = deepClone(source[k])
}
return _obj
}
}
function isObject(obj) {
//注意点:null的typeof也是object
return typeof obj === 'object' && obj !== null
}