关于javascript:Js中的浅拷贝与深拷贝

浅拷贝

浅拷贝是一种复制对象的形式,创立一个新的对象,并将原始对象的属性值复制到新对象中。然而,如果属性值是对象或者数组,浅拷贝只会复制他们的援用而不是创立正本。换句话说,浅拷贝只复制了对象外表层级,而不会递归复制外部的嵌套对象。简略来说,浅拷贝只复制对象的一层,如果原始对象中的属性值是对象,那么拷贝后的对象与原始对象共享雷同的援用,批改其中一个对象的属性值会影响到另一个对象。

对象浅拷贝形式?

  1. 应用Object.assign()
const obj = { name: "土豆", age: "18" };
const obj2 = Object.assign({}, obj);
console.log(obj2);
  1. 应用...运算符
const obj1 = { name: "土豆", age: "18" };
const obj2 = { ...obj1 };
  1. 应用for...in
const obj = { name: "土豆", age: "18" };
const obj2 = {};
for (const key in obj) {
  if (obj.hasOwnProperty(key)) {
    obj2[key] = obj[key];
  }
}
  1. 应用Object.keys
const obj = { name: "土豆", age: "18" };
const obj2 = {};

Object.keys(obj).forEach((key) => {
  obj2[key] = obj[key];
});
console.log(obj2);

数组浅拷贝实现形式?

  1. 应用slice()办法
const arr = ["土豆", "番茄", "向日葵"];
const arr2 = arr.slice();
  1. 应用concat()办法
const arr = ["土豆", "番茄", "向日葵"];
const arr2 = [].concat(arr);
  1. 应用...运算符
const arr = ["土豆", "番茄", "向日葵"];
const arr2 = [...arr];

深拷贝

深拷贝的实现形式

  1. 应用JSON.parse(JSON.stringify())
const person = {
  name: "土豆",
  age: "18",
  address: {
    city: "江苏南京",
    country: "中国",
  },
};

const person2 = JSON.parse(JSON.stringify(person));

person2.address.city = "安徽芜湖";
console.log(person2);
console.log(person);

应用JSON.parse(JSON.stringify())弊病

  • 对于对象外面的函数,undefined,Symbol,序列化后会失落

    const obj = {
     name: Symbol("土豆"),
     age: undefined,
     fun: function () {
     console.log("hello world");
     },
    };
    
    const deepCloneObj = JSON.parse(JSON.stringify(obj));
    console.log(deepCloneObj);//{}
  • 对于对象外面的RegExp、Error对象,则序列化的后果只能失去空对象

    const obj = {
     error: new Error(""),
     reg: new RegExp(),
    };
    
    const deepCloneObj = JSON.parse(JSON.stringify(obj));
    console.log(deepCloneObj);//{ error: {}, reg: {} }
  • 对象对象外面的Date对象,序列化后失去一个字符串

    const obj = {
     date: new Date(),
    };
    
    const deepCloneObj = JSON.parse(JSON.stringify(obj));
    console.log(deepCloneObj);//
  • 对于对象中的NaN、Infinity和-Infinity,则序列化后失去null

    const obj = {
     num1: 0 / 0,
     num2: 1 / 0,
     num2: -1 / 0,
    };
    
    const deepCloneObj = JSON.parse(JSON.stringify(obj));
    console.log(deepCloneObj);//{ num1: null, num2: null }
  • 不会拷贝原型链上的属性

    const protoObj = { name: "土豆" };
    const obj = Object.create(protoObj);
    obj.age = 18;
    
    const deepCloneObj = JSON.parse(JSON.stringify(obj));
    console.log(obj.name); //土豆
    console.log(deepCloneObj.name); //undefined
  1. 应用structuredClone()办法实现深拷贝,然而对于不可序列化的输出值,也会抛出谬误;

    const obj = {
      age: undefined,
    };
    
    const deepCloneObj = structuredClone(obj);
    console.log(deepCloneObj); //{}
  2. 应用递归深度拷贝对象

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理