赋值和深拷贝和浅拷贝

4 篇文章 0 订阅
2 篇文章 0 订阅

赋值 (完全一样,怎么改怎么变)

  • 概念:直接将一个对象或数组的引用赋给另一个变量。
  • 特点:新变量和原变量指向同一内存地址,改变其中一个会影响另一个。

浅拷贝 (半新,修改原数组子对象会跟着改变)

  • 概念:创建一个新对象或数组,但只复制第一层属性。
  • 实现方法:使用 Object.assign()、扩展运算符(...)等。
  • 特点:对于嵌套对象,只有引用被复制,内层对象仍然共享同一引用,改变内层对象会影响原对象。

深拷贝。(完全是新的,修改和原数据无关)

  • 概念:创建一个完全独立的新对象或数组,递归复制所有层级的属性。
  • 实现方法:可以使用 JSON 方法(JSON.parse(JSON.stringify(obj))),或第三方库(如 Lodash 的 cloneDeep)。
  • 特点:新对象与原对象完全独立,任何修改都不会相互影响。

总结

  • 赋值:引用复制。
  • 浅拷贝:一层复制,内层共享。
  • 深拷贝:完全独立的复制。

栗子:

对子对象的影响主要取决于使用的赋值方式(赋值、浅拷贝或深拷贝)。以下是对每种方式的详细说明和示例,尤其是在处理嵌套对象时如何影响原始对象。

1. 赋值

示例:
let original = { a: 1, b: { c: 2 } };
let copy = original; // 赋值

copy.a = 10;      // 修改顶层属性
copy.b.c = 20;   // 修改子对象属性

console.log(original); // { a: 10, b: { c: 20 } }
影响:
  • copy 和 original 引用相同的对象。修改 copy 直接影响 original

2. 浅拷贝

示例:
let original = { a: 1, b: { c: 2 } };
let shallowCopy = Object.assign({}, original); // 浅拷贝

shallowCopy.a = 10;      // 修改顶层属性
shallowCopy.b.c = 20;    // 修改子对象属性

console.log(original); // { a: 1, b: { c: 20 } }
影响:
  • shallowCopy 修改了 a,但 original 的 a 保持不变。
  • 但对 b.c 的修改会影响 original,因为 b 仍然是一个引用。

3. 深拷贝

示例:
let original = { a: 1, b: { c: 2 } };
let deepCopy = JSON.parse(JSON.stringify(original)); // 深拷贝

deepCopy.a = 10;      // 修改顶层属性
deepCopy.b.c = 20;    // 修改子对象属性

console.log(original); // { a: 1, b: { c: 2 } }
影响:
  • deepCopy 的修改不会影响 original,因为两个对象是完全独立的。

 

总结

  • 赋值:修改任意属性都会影响原始对象,因为它们共享同一引用。
  • 浅拷贝:顶层属性的修改不会影响原始对象,但对子对象的修改会影响原始对象,因为它们共享同一引用。
  • 深拷贝:所有修改都不会影响原始对象,两个对象完全独立。

 

 浅拷贝的方法

1. 使用 Object.assign()

Object.assign() 方法用于将一个或多个源对象的可枚举属性复制到目标对象。返回目标对象。

const original = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, original);

shallowCopy.a = 2; // 不影响 original
shallowCopy.b.c = 3; // 会影响 original

console.log(original.b.c); // 输出 3

2. 使用扩展运算符 (...)

扩展运算符是 ES6 引入的一种简便语法,允许将一个对象的可枚举属性拷贝到另一个对象。

const original = { a: 1, b: { c: 2 } };
const shallowCopy = { ...original };

shallowCopy.a = 2; // 不影响 original
shallowCopy.b.c = 3; // 会影响 original

console.log(original.b.c); // 输出 3

3. 使用 Array.prototype.slice()(用于数组)

对于数组,可以使用 slice() 方法来创建数组的浅拷贝。

const originalArray = [1, 2, { a: 3 }];
const shallowCopyArray = originalArray.slice();

shallowCopyArray[0] = 100; // 不影响 originalArray
shallowCopyArray[2].a = 200; // 会影响 originalArray

console.log(originalArray[2].a); // 输出 200

4. 使用 Array.from()

Array.from() 方法可以将类数组或可迭代对象转换为数组,并创建该数组的浅拷贝。

const originalArray = [1, 2, { a: 3 }];
const shallowCopyArray = Array.from(originalArray);

shallowCopyArray[0] = 100; // 不影响 originalArray
shallowCopyArray[2].a = 200; // 会影响 originalArray

console.log(originalArray[2].a); // 输出 200

5. 使用 Object.entries() 和 Object.fromEntries()

可以结合使用 Object.entries()Object.fromEntries() 来实现对象的浅拷贝。

const original = { a: 1, b: { c: 2 } };
const shallowCopy = Object.fromEntries(Object.entries(original));

shallowCopy.a = 2; // 不影响 original
shallowCopy.b.c = 3; // 会影响 original

console.log(original.b.c); // 输出 3

总结

浅拷贝适合简单对象或数组的复制,但要注意对引用类型属性的修改可能会影响原对象。使用时,根据实际情况选择合适的方法。

 

深拷贝的方法 

1. JSON 方法

let original = { a: 1, b: { c: 2 } };
let deepCopy = JSON.parse(JSON.stringify(original));

优点:简单易用。
缺点:无法处理函数、undefined、日期对象和正则表达式等。

2. 递归函数

function deepClone(obj) {
    if (obj === null || typeof obj !== 'object') return obj;
    const clone = Array.isArray(obj) ? [] : {};
    for (const key in obj) {
        clone[key] = deepClone(obj[key]);
    }
    return clone;
}

let deepCopy = deepClone(original);

优点:可处理复杂数据类型。
缺点:可能会导致栈溢出(对于深层嵌套)。

3. Lodash 的 cloneDeep

let _ = require('lodash');
let deepCopy = _.cloneDeep(original);

优点:功能强大,支持多种数据类型。
缺点:需要引入第三方库。

4. 使用结构化克隆

let deepCopy = structuredClone(original);

优点:原生支持,能够处理大多数数据类型。
缺点:在旧版浏览器中不兼容。

总结

选择深拷贝方法时,要根据数据结构和项目需求来决定。对于简单对象,JSON 方法方便;对于复杂结构,使用递归函数或第三方库会更安全。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值