• Js中如何克隆对象?


    原始值

    我们假设一个变量 name 具有一个与之关联的原始值(number,string,boolean,undefined 和null)。 如果我们将此变量 name 复制到另一个变量name2 ,则原始变量的任何修改都不会影响到第二个变量,因为它们是原始值。

    let name="fly63";
    let name2= name;
    console.log (name, name2); // fly63, fly63
    name="前端";
    console.log (name,name2); // 前端 fly63

    引用值

    但是,如果我们对引用类型的值进行相同的操作,则我们对一个变量所做的任何更改也将反映在另一个变量中,因为两个变量都指向同一对象。

    数组

    要拷贝数组,slice()方法用于创建数组的新副本。 可以独立修改此副本,而不会影响原始数组。

    如果未传递任何参数,则它会精确复制数组,但数字也可以作为参数传递。 如果仅传递一个数字,它将确定我们要从其进行复制的索引的值,而如果传递两个数字,则将标记开始和结束。

    // 示例1
    const names = ['fly63', '前端', 'java'];
    const names2 = names;
    console.log(names, names2);
    // ["fly63", "前端", "java"] 
    // ["fly63", "前端", "java"] 
    
    // 示例2
    names2[2] = 'web';
    console.log(names, names2);
    //  ["fly63", "前端", "web"] 
    //  ["fly63", "前端", "web"] 
    
    // 示例3
    const name2 = names.slice();
    names[2] = '前端教程';
    console.log(name2, names2)
    // ["fly63", "前端", "web"]
    //  ["fly63", "前端", "前端教程"]

    对象

    当引用值是一个对象时,也会发生同样的情况,对其属性之一的任何修改都会影响这两个变量。 若要克隆对象,请使用 Object.assign() 方法,该方法会将一个或多个源对象的所有可枚举属性的值复制到目标对象,但是此方法仅对对象的一个浅拷贝。

    // 示例1
    const names = {
      name: 'fly63',
      surname: 'web前端网'
    }
    
    const names2 = names;
    console.log(names, names2) // 打印结果是一模一样的
    
    // 示例2
    names2.surname ='web前端';
    console.log(names, names2)
    
    // {name: "fly63", surname: "web前端"}
    // {name: "fly63", surname: "web前端"}
    
    // 示例3
    const names3 = Object.assign({}, names);
    names3.surname = 'web前端网';
    console.log(names, names3)
    
    // {name: "fly63", surname: "web前端"}
    // {name: "fly63", surname: "web前端网"}
    

    要对对象进行深拷贝,需要使用其他方法。

    正如我们所说,Object.assign()方法只是一个浅拷贝(即,当我们的对象没有其他对象作为属性时)才有效。 在这些情况下,必须对对象进行深拷贝。

    与浅拷贝不同,深拷贝以递归方式复制每个子对象,直到所有涉及的对象都被复制为止。

    我们可以使用什么方法复制对象的深层副本?

    jsON.parse(jsON.stringify(obj))

    此方法使用JSON.stringify()将对象转换为字符串,然后再用JSON.parse()将其转换回对象。 此方法对简单对象有效,但如果对象属性是函数时无效。

    const names = {
      name: 'fly63',
      surname: 'web前端网',
      social: {
        wx: '大迁世界',
        url: 'www.lsp.com'
      }
    }
    const names2 = JSON.parse(JSON.stringify(names));
    names2.social.url = 'www.baidu.com';
    console.log(names, names2);
    
    /** 
    {
      name: "fly63"
      social: {wx: "大迁世界", url: "www.lsp.com"}
      surname: "web前端网"
    }
    */
    
    /** 
    {
      name: "fly63"
      social: {wx: "大迁世界", url: "www.baidu.com"}
      surname: "web前端网"
    }
    */

    http://www.bijianshuo.com 软文发稿平台

    深度拷贝

    另一种非常有趣和优雅的对象深度复制方法是使用递归函数。

    我们创建了一个deepClone(object)函数,将想要克隆的对象作为参数传递给它。在函数内部,将创建一个局部变量克隆,这是一个空对象,其中将从起始对象克隆的每个属性都将添加到该对象中。

    具体思路:

    • 如果该属性不是对象,则将其简单地克隆并添加到新的克隆对象中。
    • 如果属性是对象,则再次执行deepClone(value)函数,并将属性的值(在这种情况下为对象)作为参数传递,并重复相同的过程。
    function deepClone(object) {
      var clone = {};
      for (var key in object) {
        var value = object[key];
        if (typeof(value) !== 'object') {
          clone[key] = value;
        } else {
          clone[key]=deepClone(value);
        }
      }
      return clone;
    } 
    
    deepClone({value1:1,value2:{value3:2}});
    //{value1:1,value2:{value3:2}}
    deepClone({value1:1,value2:{value3:{value3b:3}}});
    //{value1:1,value2:{value3:{value3b:3}}}
  • 相关阅读:
    最小生成树
    BZOJ3894:文理分科(最大流)(同BZoj3438)
    BZOJ3438:小M的作物 (最大闭合权图->最小割)
    BZOJ 1305:dance跳舞(二分+最大流)
    BZOJ1266:上学路线route (最短路+最小割)
    BZOJ1854:游戏(二分图匹配)
    【PowerOJ1738】最小路径覆盖
    【SPOJ839】Optimal Marks 网络流
    【USACO】AC自动机
    【国家集训队2011】聪聪可可 树分治
  • 原文地址:https://www.cnblogs.com/qianxiaox/p/14982647.html
Copyright © 2020-2023  润新知