JS深浅拷贝---4

拷贝

内存分为栈和堆

基本数据类型存放在栈内存

引用数据类型存放在堆内存,引用数据类型的变量是一个指向堆内存中实际对象的引用,存在栈中

浅拷贝

浅拷贝:指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝

属性是基本类型,拷贝的就是基本类型的值。

  var a = 213
  var b = a
  a=31549
  console.log(a);//31549
  console.log(b);//213

如果属性是引用类型,拷贝的就是内存地址,两个都同时指向了一个空间,如果改变其中一个,另一个也会发生变化

var a = [1, 2, 3, 5]
  var b = a
  a.push(9)
  console.log(a);//[1,2,3,5,9]
  console.log(b);//[1,2,3,5,9]
  b.push(6)
  console.log(a);//[1,2,3,5,9,6]
  console.log(b);//[1,2,3,5,9,6]

在JavaScript中,存在浅拷贝的现象有:

  • Object.assign
  • Array.slice( ), Array.concat( )
  • 使用拓展运算符实现的复制

深拷贝

深拷贝开辟一个新的栈,两个对象属性完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性

JSON.stringify() / 循环递归

ES6中的两种复制的方法不会发生引用:

第一种:Array.from(要复制的数组)

  var a = [1, 2, 3, 5]
   var a1=Array.from(a)
   a.push(5)
   console.log(a);//[1, 2, 3, 5, 5]
   console.log(a1);//[1, 2, 3, 5]

第二种:展开语法(...)

var arr1=[1,2,3];
var arr2=[...arr1];
arr1.push(4);
alert(arr1);  //1234
alert(arr2);  //123
arr2.push(5);
alert(arr1);  //1234
alert(arr2);  //1235

手写深拷贝

    var obj = {
      name: '张三',
      age: 18,
      sex: '男',
      score: {
        Chinese: 100,
        english: 80,
        Math: 60
      },
      stu:[1,2,3,4,5,[7,8,9,10]]
    }

    function deepClone(obj) {
      //声明一个变量用来储存拷贝之后的内容
      var newObj = null
      //判断数据类型是否是复杂类型,如果是则调用自己,再次循环,如果不是,直接赋值即可,
      //由于null不可以循环但类型又是object,所以这个需要对null进行判断
      if (typeof (obj) == 'object' && obj !== null) {
        //变量用以储存拷贝出来的值,根据参数的具体数据类型声明不同的类型来储存
        newObj = obj instanceof Array ? [] : {}
        //循环obj 中的每一项,如果里面还有复杂数据类型,则直接利用递归再次调用copy函数
        for (var key in obj) {
          newObj[key] = deepClone(obj[key])
        }
      } else {
        // 如果没有复杂数据类型了,直接输出
        newObj = obj
      }
      //返回拷贝的数据
      return newObj
    }
    let a = deepClone(obj)
    console.log(a);
    obj.age = 30
    console.log(obj, a);

写这个深拷贝的时候,首先要想到 数据类型:原始数据类型  number null  boolen  undefined  string  Symbol   引用数据类型:Object Array Function  

第一个点是:要去判断这个数据的数据类型是否是对象

第二个点是:如果是引用数据类型的话,它是数组还是对象,那要拷贝一个数据,你需要一个变量去收集  var newObj=[ ]:{ }

第三个点是:循环遍历这个数据,数据如果是多层的话就重新调用一遍这个,如果没有了,就直接赋值   返回这拷贝的数据

 

posted @ 2022-06-20 17:10  长安·念  阅读(30)  评论(0)    收藏  举报