首页 > 编程知识 正文

js深拷贝和浅拷贝的方法,js 深浅拷贝

时间:2023-05-06 10:35:21 阅读:182596 作者:2853

概念

    深拷贝和浅拷贝只针对像 Object, Array 这样的复杂对象。它们最根本的区别在于是否真正获取了一个对象的复制实体,而不是引用。简单来说,假设B复制了A,当修改B时,看A是否会发生变化,如果A变了,说明是浅拷贝;如果A没变,那就是深拷贝

浅拷贝 1. 用 = 号赋值引用地址 let obj = { name: '大气的柚子', age: 20, sex: '男', tel: /^1[345789]d{9}$/, address: undefined, flag: true, school: {colleges: "野鸡烧烤工程系"grade: 2020name: '野鸡大学'stuNo: 2020123456}, say: () => { console.log('哇塞') }};let obj2 = obj;obj2.name = 'Rose';obj2.sex = '女';obj2.school.name = '野鸡变凤凰';console.log('obj', obj);console.log('obj2', obj2); 2. for…in

    被循环的对象存在嵌套对象时为浅拷贝

let obj = { name: '大气的柚子', age: 20, tel: /^1[345789]d{9}$/, address: undefined, flag: true, school: { name: '野鸡大学', grade: 2020, stuNo: 2020123456, colleges: '野鸡烧烤工程系', }, say: () => { console.log('哇塞') }};let obj2 = {};for (let key in obj) { obj2[key] = obj[key];}obj2.name = 'zxdbq';obj2.sex = '男';obj2.school.name = '野鸡变凤凰';console.log('obj', obj);console.log('obj2', obj2); 3. Object.assign()

    ① Object.assign()只有源对象,没有目标对象时为浅拷贝

let obj = { name: '大气的柚子', age: 20, sex: null, tel: /^1[345789]d{9}$/, address: undefined, flag: true, school: { name: '野鸡大学', grade: 2020, stuNo: 2020123456, colleges: '野鸡烧烤工程系', }, say: () => { console.log('哇塞') }};let obj2 = Object.assign(obj);obj2.name = 'Rose';obj2.school.name = '野鸡变凤凰';console.log('obj', obj);console.log('obj2', obj2);

    ② Object.assign() 是一种可以对非嵌套对象进行深拷贝的方法,如果对象中出现嵌套情况,那么其对被嵌套对象的行为就成了普通的浅拷贝

let obj = { name: '大气的柚子', age: 20, sex: null, tel: /^1[345789]d{9}$/, address: undefined, flag: true, school: { name: '野鸡大学', grade: 2020, stuNo: 2020123456, colleges: '野鸡烧烤工程系', }, say: () => { console.log('哇塞') }};let obj2 = { name: 'xqdgb', school: { name: '凤凰大学' }};Object.assign(obj2, obj);obj2.name = 'zxdbq';obj2.school.name = '野鸡变凤凰';console.log('obj', obj);console.log('obj2', obj2); 深拷贝 1. JSON.parse(JSON.stringify()) let obj = { name: '大气的柚子', age: 20, sex: null, tel: /^1[345789]d{9}$/, address: undefined, flag: true, school: { name: '野鸡大学', grade: 2020, stuNo: 2020123456, colleges: '野鸡烧烤工程系', }, say: () => { console.log('哇塞') }};let obj2 = JSON.parse(JSON.stringify(obj));obj2.name = 'zxdbq';obj2.school.name = '野鸡变凤凰';console.log(obj);console.log(obj2);

    注意:这种方式无法拷贝 正则表达式,undefine,function

2. for…in

    被循环的对象不存在嵌套对象时为深拷贝

let obj = { name: '大气的柚子', age: 20, sex: '男', tel: /^1[345789]d{9}$/, address: undefined, flag: true, say: () => { console.log('哇塞') }};let obj2 = {};for (let key in obj) { obj2[key] = obj[key];}obj2.name = 'Rose';obj2.sex = '女';console.log('obj', obj);console.log('obj2', obj2); 3. Object.assign()

    Object.assign() 方法只复制源对象中可枚举的属性和对象自身的属性。如果目标对象中的属性具有相同的键,则属性将被源中的属性覆盖

let obj = { name: '大气的柚子', age: 20, sex: null, tel: /^1[345789]d{9}$/, address: undefined, flag: true, say: () => { console.log('哇塞') }};let obj2 = { name: 'xqdgb',};Object.assign(obj2, obj);obj2.name = 'zxdbq';console.log('obj', obj);console.log('obj2', obj2); 4. 递归

    递归拷贝所有层级属性

let obj = { name: '大气的柚子', age: 20, sex: null, tel: /^1[345789]d{9}$/, address: undefined, flag: true, school: { name: '野鸡大学', grade: 2020, stuNo: 2020123456, colleges: '野鸡烧烤工程系', }, say: () => { console.log('哇塞') }}function deepClone(obj) { let objClone = Array.isArray(obj) ? [] : {}; if(obj && typeof obj === 'object' ) { for(key in obj) { if(obj.hasOwnProperty(key)){ // 判断 obj 子元素是否为对象,如果是则递归复制 if(obj[key] && typeof obj[key] === 'object') { objClone[key] = deepClone(obj[key]); } else { // 如果不是则直接复制 objClone[key] = obj[key]; } } } } return objClone;}let obj2 = deepClone(obj);obj2.name = 'Rose';obj2.school.name = '野鸡变凤凰';console.log('obj', obj);console.log('obj2', obj2); 5. $.extend()

    通过 jQuery 的 extend() 方法实现深拷贝,第一个参数 true 为深拷贝,false 为浅拷贝

let obj = { name: '大气的柚子', age: 20, sex: null, tel: /^1[345789]d{9}$/, address: undefined, flag: true, school: { name: '野鸡大学', grade: 2020, stuNo: 2020123456, colleges: '野鸡烧烤工程系', }, say: () => { console.log('哇塞') }}var obj2 = $.extend(true, {}, obj); // true 为深拷贝,false 为浅拷贝obj2.name = 'Rose';obj2.school.name = '野鸡变凤凰';console.log('obj', obj);console.log('obj2', obj2); 6. slice()

    slice() 对数组进行深拷贝

let arr = [1, 2, 3, 4, 5, 6];let arr2 = arr.slice(0);arr2[0] = 'Rose';arr2[1] = '女';console.log('arr', arr); // [1, 2, 3, 4, 5, 6]console.log('arr2', arr2); // ["Rose", "女", 3, 4, 5, 6] 7. concat()

    concat() 对数组进行深拷贝

let arr = [1, 2, 3, 4, 5, 6];let arr2 = arr.concat();arr2[0] = 'Rose';arr2[1] = '女';console.log('arr', arr); // [1, 2, 3, 4, 5, 6]console.log('arr2', arr2); // ["Rose", "女", 3, 4, 5, 6]

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。