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

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

     最近自己面试被问到浅拷贝、深拷贝,关键是自己一时回答不上了,所以恶补一下。

    我们都知道js的数据类型分为基本类型和引用类型,一般讨论到浅拷贝和深拷贝的都是针对引用类型的,像Object和Array这样的复杂类型

    1、浅拷贝:以Object为例

    var  a  =  {
        name:  'liner'
    };
    
    var  b  =  a;
    b.name  =  'Jiejie';
    console.log(b.name);    // Jiejie
    console.log(a.name);    // Jiejie

      可以看出,对于Object类型,当我们将a赋值给b,然后更改b中的属性,a也会随着变化。
      也就是说a和b指向了同一块内存,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝。

    2、深拷贝

    我们如果给b放到新的内存中,将a的各个属性都复制到新内存里,就是深拷贝。
    也就是说,当b中的属性有变化的时候,a内的属性不会发生变化。

    二、浅拷贝的实现

    1、Object.assign()

    用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。 

    var  target  =  {a:  1,  b:  1};
    var  obj1  =  {a:  2,  b:  2,  c: {ca:1}};
    var  obj2  =  {c:  {ca:  3,  cb:  2,  cd:  1}};
    var  result  =  Object.assign(target,  obj1,  obj2);
    
    console.log(target);    // {a: 2, b: 2, c: {ca: 3, cb: 2, cd: 1}}
    console.log(target  ===  result);    // true
    可以看到,Object.assign()拷贝的只是属性值,假如源对象的属性值是一个指向对象的引用,它也只拷贝那个引用值。所以Object.assign()只能用于浅拷贝或是合并对象。这是Object.assign()值得注意的地方。

     

    
    
    
    

    三、深拷贝的实现

    1、层级拷贝,用递归实现。

        function deepClone(obj){
            //定义对象来判断当前的参数是数组还是对象
            let objClone = Array.isArray(obj)?[]:{};
            //如果obj存在并且为对象        
            if(obj&&typeof obj == "object"){
                for(let key in obj){
                    if(obj.hasOwnProperty(key)){
                        //如果obj的子元素为对象,那么递归(层级遍历)
                        if(obj[key]&&typeof obj[key] == "object"){
                            objClone[key] = deepClone(obj[key]);
                        }else{
                        //如果不是,直接赋值
                            objClone[key] = obj[key];
                        }
                    }
                }
            }    
            return objClone;
        }

    2、JSON解析(底层原理也是层级遍历)

    var a =  [0,1,2,[3,4],5];
    var b = JSON.parse(JSON.stringify(a));
    console.log(b); //[0,1,2,[3,4],5];
    console.log(a  ===  b);    // false

     b就是拷贝的结果,修改b不影响a。但是这种方法也有缺陷:

    1. 无法复制函数
    2. 原型链没了,对象就是object,所属的类没了。
  • 相关阅读:
    leetcode——33.搜索旋转排序数组
    leetcode——80.删除排序数组中的重复项2
    leetcode——26.删除排序数组中的重复项
    leetcode——18.四数之和
    leetcode——42.接雨水
    leetcode——11.盛最多水的容器
    leetcode——16.最接近的三数之和
    leetcode——15.三数之和
    leetcode——1002.查找常用字符
    004 linux学习:【第4篇】之nginx
  • 原文地址:https://www.cnblogs.com/aixue/p/13236471.html
Copyright © 2011-2022 走看看