zoukankan      html  css  js  c++  java
  • js深拷贝和浅拷贝

    一、关于数组的拷贝

    常见问题:

      let arr = [1, 2, 3, 4];
      let arr2 = arr
      arr2[2] = 10;
      console.log(arr[2]);   // 10
      console.log(arr2[2]);   //10

    我们只想改变arr2的值,保持arr不变,但是实际上两个都会变,这是因为在js中,我们复制对象或者数组实际上只是复制了它的地址,而不是复制的真实的值,这就是我们常说的深拷贝和浅拷贝的区别:

    深复制:将变量的数据赋值给对应变量

    浅复制:将变量的存储地址赋值给对应变量

    解决办法:

    1.利用数组的slice(start [,end]):该方法可以返回一个数组的其中某部分元素,具体使用可以参见 slice()的使用方法,当我们start为0并且不设置end参数时默认取数组的所有元素

    let arr2 = arr.slice(0);

    2.利用数组的concat(): 该方法用于连接两个或多个数组,返回一个新数组,不会改变当前数组

    let arr2 = arr.concat();

    二、关于对象的拷贝

    常见问题:

    let person={
    name:'张三',
    age:12,
    family:['mom','dad','son'],
     teacher: {
      math: 'wang',
      english: 'chen'
     }
    }
    let person2 = person;
    person2.name = '李四';
    console.log(person2.name); //李四
    console.log(person.name); //李四

    同理,我们也不想改变person的属性,只想改变person2的属性

    解决办法:

    1.利用JSON.stringify()和JSON.parse()进行转换

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

     2.用for...in... 遍历属性

        function cloneObj(obj) {
            var newObj = {};
            if(typeof obj !== 'object'){
                return;
            }
            for(var i in obj){
                newObj[i] = obj[i];
            }
            return newObj;
        }
        var newObj = cloneObj(obj);
    

      这种方法也能达到拷贝的目的,但是我们接下来执行下面代码:

       newObj.age=15;
        newObj.teacher.math = 'yan';
        console.log(newObj.teacher.math, newObj.age);   // yan   15
        console.log(obj.teacher.math, obj.age);   // yan   12
    

      我们发现改变newObj的第一层属性的时候是不会影响obj的,但我们改变第二层属性(teacher属性的math属性)的时候obj依然会受影响,怎么办呢?我们将上面方法进行改进一下:

    function cloneObj(obj) {
            var newObj = {};
            if(typeof obj !== 'object'){
                return;
            }
            for(var i in obj){
                newObj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i];
            }
            return newObj;
        }
    

     利用这种递归的方法就可以避免上述问题。

  • 相关阅读:
    下载安装Apacheweb
    灵魂拷问第4篇:说一说从输入URL到页面呈现发生了什么?——解析算法篇
    灵魂拷问第3篇:说一说从输入URL到页面呈现发生了什么?——网络篇
    灵魂拷问第2篇:能不能说一说浏览器的本地存储?各自优劣如何?
    灵魂拷问第1篇:能不能说一说浏览器缓存?
    为什么是三次握手和四次挥手?
    http协商缓存VS强缓存
    版本管理之Git神器
    JavaScript 运行原理
    「动画演示」:变量提升别有一翻风味
  • 原文地址:https://www.cnblogs.com/qilj/p/7081857.html
Copyright © 2011-2022 走看看