美文网首页前端
JavaScript 深拷贝和浅拷贝

JavaScript 深拷贝和浅拷贝

作者: 暴躁程序员 | 来源:发表于2022-03-24 17:40 被阅读0次

拷贝的意思就是复制数据,打个比方,原有一个变量 a 的值是引用类型数据,要求新创建的变量 b 的值与 a 的值相同,
方案一(浅拷贝):让 b 直接共享a 的数据,那么 a 和 b 任何一方修改数据,另一方的数据也会同步变化
方案二(深拷贝):让 b 创建一个新的空间用来存储和 a 一样的数据,即 将 a 的数据,以递归的方式拷贝到 b 新创建的数据空间中

注意:

  1. 基础数据类型的值存储于栈中,他不涉及深浅拷贝(全是深拷贝)
  2. 引用类型的地址存储于栈中,指针指向存储于堆中的值,且其他变量的指针可通过赋值的方式指向同一个堆中的值,当堆中的值发生改变时,会造成所有变量的值同步变化

总结:浅拷贝 --- 拷贝引用类型的地址,深拷贝 --- 拷贝引用类型的值

浅拷贝

  1. 变量赋值的方式实现 数组和对象 的浅拷贝
// 数组浅拷贝
let a = [1, 2, 3, 4, 5];
let b = a;
b[0] = 1000; // 改变 b 的时候,同时也会改变 a
console.log(a); // [ 1000, 2, 3, 4, 5 ]

// 对象浅拷贝
let c = { name: 1, age: 1 };
let d = c;
d.name = 1000; // 改变 d 的时候,同时也会改变 c
console.log(c); // { name: 1000, age: 1 }
  1. Object.assign() 实现 对象 浅拷贝
// 对象浅拷贝
let a = { name: 1, age: 1 };
let b = Object.assign(a, { other: 999 });
b.name = 1000; // 改变 b 的时候,同时也会改变 a
console.log(a); // { name: 1000, age: 1, other: 999 }

// 注意:Object.assign的用法,a 写在第一位才是浅拷贝,写成Object.assign({ other: 999 }, a) ,是深拷贝
let c = Object.assign({ other: 999 }, a);
c.name = 888; // 改变 c 的时候,a 不会变化
console.log(a); // { name: 1000, age: 1, other: 999 }

深拷贝

  1. 递归的方式实现 数组和对象 的深拷贝
// 数组深拷贝
let a = [1, 2, 3, 4, 5];
let b = [];
for (let i = 0; i < a.length; i++) {
  b.push(a[i]);
}
b[0] = 1000; // 改变 b 的时候,a 不受影响
console.log(b); // [ 1000, 2, 3, 4, 5 ]
console.log(a); // [ 1, 2, 3, 4, 5 ]

// 对象深拷贝
let c = { name: 1, age: 1 };
let d = {};
for (const k in c) {
  if (Object.hasOwnProperty.call(c, k)) {
    d[k] = c[k];
  }
}
d.name = 1000; // 改变 d 的时候,c 不受影响
console.log(c); // { name: 1, age: 1 }
console.log(d); // { name: 1000, age: 1 }
  1. ... 拓展运算符的方式实现 数组和对象 的深拷贝
// 数组深拷贝
let a = [1, 2, 3, 4, 5];
let b = [...a];
b[0] = 1000; // 改变 b 的时候,a 的值不变
console.log(a); // [1, 2, 3, 4, 5];
console.log(b); // [ 1000, 2, 3, 4, 5 ]

// 对象深拷贝
let c = { name: 1, age: 1 };
let d = { ...c };
d.name = 1000; // 改变 d 的时候,c 的值不会变
console.log(c); // { name: 1, age: 1 }
console.log(d); // { name: 1000, age: 1
  1. 数组的 sliceconcat方法实现 数组 的深拷贝
// slice 实现 数组深拷贝
let a = [1, 2, 3, 4, 5];
let b = a.slice();
b[0] = 1000; // 改变 b 的时候,a 的值不变
console.log(a); // [1, 2, 3, 4, 5];
console.log(b); // [ 1000, 2, 3, 4, 5 ]

// concat 实现 数组深拷贝
let c = [1, 2, 3, 4, 5];
let d = a.concat();
d[0] = 1000; // 改变 b 的时候,a 的值不变
console.log(c); // [1, 2, 3, 4, 5];
console.log(d); // [ 1000, 2, 3, 4, 5 ]

相关文章

  • 浅拷贝和深拷贝

    本文参考:JavaScript中的浅拷贝和深拷贝js 深拷贝 vs 浅拷贝深入剖析 JavaScript 的深复制...

  • 深入理解JavaScript中的堆与栈 、浅拷贝与深拷贝

    JavaScript中的浅拷贝与深拷贝 学了这么长时间的JavaScript想必大家对浅拷贝和深拷贝还不太熟悉吧,...

  • js浅拷贝和深拷贝

    javaScript的变量类型 javaScript的变量类型基本类型:引用类型: 浅拷贝和深拷贝的区分 浅拷贝浅...

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

  • JavaScript深拷贝、浅拷贝

    JavaScript深拷贝、浅拷贝 浅拷贝:浅拷贝只是复制了内存地址,如果原地址中的对象改变了,浅拷贝出来的对象也...

  • 初探浅拷贝&深拷贝

    思考 这个代码为什么具有深拷贝作用 浅拷贝与深拷贝 在JavaScript中,对于Object和Array这类引用...

  • 理解JavaScript中浅拷贝和深拷贝的区别

    要理解 JavaScript中浅拷贝和深拷贝的区别,首先要明白JavaScript的数据类型 JavaScript...

  • 浅拷贝和深拷贝

    今天来讨论一下javascript中的浅拷贝和深拷贝。 首先我们先来看一下两个问题: 1.什么叫浅拷贝和深拷贝? ...

  • iOS面试题-第二页

    11.深拷贝和浅拷贝的理解. 深拷贝;拷贝的内容. 浅拷贝:拷贝的指针. 深拷贝如: NSMutableDicti...

  • iOS - copy 与 mutableCopy

    一说到拷贝,就不得不提浅拷贝和深拷贝。 何谓浅拷贝?何谓深拷贝? 往简单的说: 浅拷贝:拷贝地址。 深拷贝:拷贝内...

网友评论

    本文标题:JavaScript 深拷贝和浅拷贝

    本文链接:https://www.haomeiwen.com/subject/vmhljrtx.html