深浅拷贝

赋值

  • 基本数据类型(string, number, boolean, null, undefined, Symbol): 赋值,两个变量互不影响

    1
    2
    3
    4
    5
    let a = 'haha';
    let b = a;
    a = 'hahaha';
    console.log(a); // hahaha
    console.log(b); // haha
  • 引用数据类型(object): 赋址,两个变量具有相同的引用,指向同一个对象,相互之间有影响

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    let a = {
    name: 'haha',
    book: {
    title: 'JS',
    price: 40
    }
    }
    let b = a;
    a.name = 'hahaha';
    a.book.price = 50;
    console.log(a); // {name: 'hahaha', book: {title: 'JS', price: 50}}
    console.log(b); // {name: 'hahaha', book: {title: 'JS', price: 50}}

浅拷贝

  • 概念
    创建一个对象,有原始对象属性值的一份精确拷贝。
    基本类型: 拷贝
    引用类型: 拷贝内存地址,其中一个对象改变了地址,会影响到另一个对象

  • 场景

    • Object.assign()

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      let a = {
      name: 'haha',
      book: {
      title: 'JS',
      price: 40
      }
      }
      let b = Object.assign({}, a);
      a.name = 'hahaha';
      a.book.price = 50;
      console.log(a); // {name: 'hahaha', book: {title: 'JS', price: 50}}
      console.log(b); // {name: 'haha', book: {title: 'JS', price: 50}}
    • Spread展开运算符
      同Object.assign()

    • slice()
      slice() 方法返回一个新的数组对象,这一对象是一个由 begin和 end(不包括end)决定的原数组的浅拷贝。原始数组不会被改变。
      1
      2
      3
      4
      5
      6
      let a = [0, "1", [2, 3]];
      let b = a.slice(1);
      a[1] = "99";
      a[2][0] = 4;
      console.log(a); // [0, "99", [4, 3]]
      console.log(b); // ["1", [4, 3]]

深拷贝

深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。拷贝前后两个对象互不影响。

  • 使用场景
    JSON.parse(JSON.stringfy(object))

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    let a = {
    name: "haha",
    book: {
    title: "JS",
    price: 45
    }
    }
    let b = JSON.parse(JSON.stringify(a));
    a.name = 'change';
    a.book.price = 100;
    console.log(a); // {name: 'change', book: {title: 'JS', price: 100}}
    console.log(b); // {name: 'haha', book: {title: 'JS', price: 45}}
  • 问题

    • undefined, Symbol, 函数,会直接忽略

      1
      2
      3
      4
      5
      6
      7
      8
      let obj = {
      name: 'haha',
      a: undefined,
      b: Symbol('haha'),
      c: function() {}
      }
      let b = JSON.parse(JSON.stringfy(obj));
      console.log(b); // {name: 'haha'}
    • 循环引用,会报错

    • new Date情况下,转换结果不正确
    • 不能处理正则
和原数据是否指向同一对象 第一层数据为基本数据类型 原数据中包含子对象
赋值 改变使原数据一同改变 改变使原数据一同改变
浅拷贝 改变不会使原数据一同改变 改变使原数据一同改变
深拷贝 改变不会使原数据一同改变 改变不会使原数据一同改变
-------------本文结束感谢您的阅读-------------
坚持原创,感谢支持!