首页 前端知识 深拷贝浅拷贝方法总结

深拷贝浅拷贝方法总结

2024-03-05 09:03:27 前端知识 前端哥 784 132 我要收藏

目录

一、浅拷贝

1.概念:

2.实现方法

2.1 Object.assign(target,…source)

2.2 Array.prototype.slice()

2.3 Array.prototype.concat()

二、深拷贝

1. 概念

2. 实现方法

2.1 _.cloneDeep()

2.2 Json.parse(Json.stringify(obj))

2.3 JQuery中&.extend(deep,{},obj)

2.4 循环递归

一、浅拷贝

1.概念:

       如果属性是基本类型,则为值传递,如果属性是引用类型则拷贝内存地址,即共用内存地址,改变任意一个则另一个内存地址指向也变化。

2.实现方法

  • Object.assign(target,…source)
  • Array.prototype.slice()
  • Array.prototype.concat()

2.1 Object.assign(target,…source)

var obj1 = {
name : 'ggg',
age : 18,
sex : '女',
stu : {
name :'mmm'
}
}
var obj2 = Object.assign({},obj1)
console.log(obj2)
obj1.name = 'hhh';
obj2.stu.name = 'kkk';
console.log(obj1);
console.log(obj2);
复制

控制台输出为:

1)、Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象,继承属性和不可枚举属性是不能拷贝的。

2)、针对深拷贝,需要使用其他办法,因为 Object.assign()拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。

3)、目标对象自身也会改变

4)、异常会打断后续拷贝任务

5)、目前IE浏览器不兼容Object.assign(),如果需要兼容IE的话最好不要直接使用这个方法。

2.2 Array.prototype.slice()

var arr = ['a','b','c'];
var arr1 = arr.slice(0)
console.log(arr1);
arr1[1] = 'd';
console.log(arr1);
console.log(arr);
复制

控制台输出结果为:

2.3 Array.prototype.concat()

var arr = ['a','b','c'];
var arr1 = arr.concat()
console.log(arr1);
arr[2] = 'd';
console.log(arr1);
console.log(arr);
复制

二、深拷贝

1. 概念

        新开辟一个新的栈,所有元素或属性均完全赋值,与源对象完全脱离,对应两个不同的地址,新对象修改不会反映到源对象中。

2. 实现方法

2.1 _.cloneDeep()

const obj2 = _.cloneDeep(obj1);
复制

2.2 Json.parse(Json.stringify(obj))

const obj2 = JSON.parse(JSON.stringify(obj1));
复制

      但是这种方式存在弊端,会忽略undefinedsymbol函数。

2.3 JQuery中&.extend(deep,{},obj)

使用之前先引入JQuery

<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
复制
var obj1 = {
name : undefined,
name2 : 'ggg',
age : 18,
b : { f : { g : 2} },
c : [ 3,4,5 ],
d : function() {
sex = 'nv'
},
s : Symbol('A')
};
const obj2 = $.extend(true,{},obj1)
console.log(obj2);
obj1.age = 45;
obj2.b.f.g = 7
console.log(obj1);
console.log(obj2);
复制

控制台输出:

2.4 循环递归

// 递归调用
const deepCopy = (obj) => {
// 判断传入的值是否为一个对象
if (obj === null && typeof obj !== "object") {
return obj;
}
// 判断对象的类型 注意这里不考虑包装类对象
if (Object.prototype.toString.call(obj) === "[object Date]") {
return new Date(obj);
}
if (Object.prototype.toString.call(obj) === "[object RegExp]") {
return new RegExp(obj);
}
if (Object.prototype.toString.call(obj) === "[object Undefined]") {
return new Error(obj);
}
// 判断对象是类
let newObj = Array.isArray(obj) ? [] : {}
for(let item in obj){
if(typeof obj[item] === 'object') {
newObj[item] = deepCopy(obj[item])
}else {
newObj[item] = obj[item]
}
}
return newObj
};
const obj2 = deepCopy(obj1)
console.log(obj1);
obj2.age = 25;
console.log(obj1);
console.log(obj2);
复制

 控制台输出:

转载请注明出处或者链接地址:https://www.qianduange.cn//article/3281.html
标签
评论
发布的文章

jQuery实现轮播图

2024-02-26 20:02:24

响应式布局的五种方法

2024-03-27 10:03:14

前端实现3D旋转木马相册

2024-03-27 10:03:07

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!