美文网首页
如何理解js中的深拷贝和浅拷贝

如何理解js中的深拷贝和浅拷贝

作者: 前端葱叶 | 来源:发表于2020-10-24 21:07 被阅读0次

小记~

一、什么是深拷贝、浅拷贝?

const A = [1,2,3,4,[5,6]]
浅拷贝:也就是拷贝A对象里面的数据,但是不拷贝A对象里面的子对象
深拷贝:会克隆出一个对象,数据相同,但是引用地址不同(就是拷贝A对象里面的数据,而且拷贝它里面的子对象)

二、深拷贝和浅拷贝有什么区别?

三、深拷贝和浅拷贝如何实现?

浅拷贝:

  1. arr.concat()
test1() {
      const arr = [1, 2, 3, 4, [5, 6]];
      const copy = arr.concat();
      // 改变基本数据类型,不会改变原始值
      copy[0] = 99;
      console.log("改变基本数据类型:", arr);

      // 改变引用类型,改变原始值
      copy[4][1] = 77;
      console.log("改变引用类型:", arr);
    },
  1. Object.assign({}, obj1)
 test2() {
      const obj1 = { x: 1, y: 2 };
      const obj2 = Object.assign({}, obj1);

      obj2.x = 22; //修改obj2.x,改变对象中的基本类型值
      console.log("obj1:", obj1);
      console.log("obj2:", obj2);

      const obj3 = {
        x: 33,
        y: {
          m: 33,
        },
      };
      const obj4 = Object.assign({}, obj3);
      obj4.y.m = 44;
      console.log("浅拷贝:");
      console.log("obj3:", obj3); //{x:33,y:{ m:44}};
      console.log("obj4:", obj4); //{x:33,y:{ m:44}};
    },

深拷贝:

  1. JSON.parse(JSON.stringify(obj1))
test3() {
      const obj1 = {
        x: 1,
        y: {
          m: 1,
        },
      };
      const obj2 = JSON.parse(JSON.stringify(obj1));
      console.log("深拷贝:");
      console.log("obj1:", obj1);//{x:1,y:{ m:1}};
      console.log("obj2:", obj2);//{x:1,y:{ m:1}};

      obj2.y.m = 2;
      console.log("修改obj2.y.m:");
      console.log("obj1:", obj1);//{x:1,y:{ m:1}};
      console.log("obj2:", obj2);//{x:1,y:{ m:2}};
    }

2.递归

    test4() {
      const obj1 = {
        x: {
          m: 1,
        },
        y: undefined,
        z: function add(z1, z2) {
          return z1 + z2;
        },
        a: Symbol("foo"),
      };
      console.log("采用递归方式进行深拷贝:");
      const obj2 = this.deepCopy(obj1);
      obj2.x.m = 2;
      console.log(obj1);
      console.log(obj2);
    },

    // 深拷贝-递归
    deepCopy(obj) {
      // 创建一个新对象
      let result = {};
      let keys = Object.keys(obj),
        key = null,
      temp = null;

      for (let i = 0; i < keys.length; i++) {
        key = keys[i];
        temp = obj[key];
        // 如果字段的值是一个对象则递归操作
        if (temp && typeof temp === "object") {
          result[key] = this.deepCopy(temp);
        } else {
          result[key] = temp;
        }
      }
      return result;
    },

四、使用JSON.parse(JSON.stringfy(obj))深拷贝有什么缺点?

缺点:

  1. obj里面有时间对象,采用JSON.parse(JSON.stringify(obj1))深拷贝之后,时间只是字符串形式,而不是时间对象
test3(){
 var obj3 = {
        name: "a",
        date: [new Date(1536627600000), new Date(1540047600000)],
      };

      var copyedObj3 = JSON.parse(JSON.stringify(obj3));
      console.log(copyedObj3);//{name: "a",date: (2) ["2018-09-11T01:00:00.000Z", "2018-10-20T15:00:00.000Z"]}
}

2.如果obj里面有正则RegExp、Error对象,则序列化的结果将只得到空对象

test5(){
const obj5 = {
        name: "a",
        date: new RegExp("\\w+"),
      };
      const copyedObj5 = JSON.parse(JSON.stringify(obj5));
      console.log("obj5:", obj5);//{name: "a",date: /\w+/}
      console.log("copyedObj5:", copyedObj5);//{name: "a",date: {}}
}

3.如果obj里面有函数、undefined,则序列化的结果会把函数或undefined丢失

test6(){
 const obj6 = {
        name: "a",
        date: function() {
          console.log("我是obj里面的函数");
        },
      };
      const copyedObj6 = JSON.parse(JSON.stringify(obj6));
      console.log("obj6:", obj6);//{name: "a",date:f date()
      console.log("copyedObj6:", copyedObj6);//{name: "a"}

      const obj7 = {
        name: "a",
        date: undefined,
      };
      const copyedObj7 = JSON.parse(JSON.stringify(obj7));
      console.log("obj7:", obj7);//{name: "a", date: undefined}
      console.log("copyedObj7:", copyedObj7);//{name: "a"}
}
  1. 如果obj里面有NaN、Infinity和-Infinity,则序列化的结果会变成null
test8(){
const obj8 = {
        name: "a",
        date: NaN,
      };
      const copyedObj8 = JSON.parse(JSON.stringify(obj8));
      console.log("obj8:", obj8);//{name: "a", date: NaN}
      console.log("copyedObj8:", copyedObj8);{name: "a", date: null}
}

五、深拷贝和浅拷贝涉及到其他知识:

1、什么是JS的基本数据类型和引用类型?有什么区别?

2、什么是堆和栈?有什么区别?

3、堆和栈的数据结构是什么样的?

4、如何理解什么是传值,什么是传址?

5、堆和栈的图示改怎么画?如:Var user = {name:'张三'}

相关文章

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • 浅拷贝和深拷贝

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

  • JS实现深拷贝、instanceof、判断是否为数组

    JS深拷贝 JS中拷贝对象可以按照拷贝的程度可以分为浅拷贝和深拷贝,有些时候我们需要拷贝之后的对象和拷贝之前的对象...

  • JS中对象的复制

    JS中的对象复制分为两种情况:深拷贝和浅拷贝。深拷贝和浅拷贝的区别在于对数组和对象的拷贝,对它们拷贝时浅拷贝只是拷...

  • iOS面试题-第二页

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

  • js浅拷贝深拷贝

    js浅拷贝,深拷贝的简单实现 基础数据 浅拷贝 深拷贝

  • 实现一个深拷贝

    深拷贝和浅拷贝是针对复杂数据类型来说的,浅拷贝只拷贝一层,而深拷贝是层层拷贝。 代码中理解...

  • 五、面试总结(五)

    对象 拷贝(clone) 如何实现对象克隆 深拷贝和浅拷贝区别 深拷贝和浅拷贝如何实现激活机制 写clone()方...

  • js的深拷贝与浅拷贝及实现方法

    前提 理解深拷贝和浅拷贝之前,我们先理解下js变量的存储方式。 js变量分为基础类型(Undefined、Null...

  • 如何理解js中的深拷贝和浅拷贝

    小记~ 一、什么是深拷贝、浅拷贝? const A = [1,2,3,4,[5,6]]浅拷贝:也就是拷贝A对象里面...

网友评论

      本文标题:如何理解js中的深拷贝和浅拷贝

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