zoukankan      html  css  js  c++  java
  • JavaScript 复制变量的三种方法

    参考:Copying Objects in JavaScript - Orinami Olatunji(@orinamio_) October 23, 2017

     
     直接将一个变量赋给另一个变量时,系统并不会创造一个新的变量,而是将原变量的地址赋给了新变量名。举个栗子:
    let obj = {
      a: 1,
      b: 2,
    };
    let copy = obj;
    
    obj.a = 5;
    console.log(copy.a);
    // Result 
    // a = 5; // 更改obj的值,copy变量的值也会改变

    文章中提到了很多种办法,本文只选择了三种普遍的用法并分析了各自的优缺点,以及什么情况下使用哪种是最好的。

    1. 原生方法解决

    最简单的办法就是一个一个循环复制给新的变量。举栗:

    function copy(mainObj) {
      let objCopy = {}; // objCopy will store a copy of the mainObj
      let key;
    
      for (key in mainObj) {
        objCopy[key] = mainObj[key]; // copies each property to the objCopy object
      }
      return objCopy;
    }
    
    const mainObj = {
      a: 2,
      b: 5,
      c: {
        x: 7,
        y: 4,
      },
    }
    
    console.log(copy(mainObj));

    缺点:

    1. objCopy 的Object.prototype 方法与mainObj 会不一样,通常情况下我们需要完全一样的副本时,这个办法并不适用。

    2. 麻烦而且费时费事,代码无法重用。

    3. 如果原来的变量中包含Object类型,复制时还是会把这个子变量的索引交给新的变量,并不是创建了新的副本。

    2. 深度复制

    利用JSON转换来复制变量。先将原先的变量转换为String然后再重新组装成JSON,这样会产生一个不一样的副本。

    let obj = { 
      a: 1,
      b: { 
        c: 2,
      },
    }
    
    let newObj = JSON.parse(JSON.stringify(obj));
    
    obj.b.c = 20;
    console.log(obj); // { a: 1, b: { c: 20 } }
    console.log(newObj); // { a: 1, b: { c: 2 } } (New Object Intact!)

    缺点:

    1. 变量很多的时候非常耗时耗内存。

    3. 使用Object.assign()

    使用举例:

    // circular object
    let obj = { 
      a: 'a',
      b: { 
        c: 'c',
        d: 'd',
      },
    }
    
    obj.c = obj.b;
    obj.e = obj.a;
    obj.b.c = obj.c;
    obj.b.d = obj.b;
    obj.b.e = obj.b.c;
    
    let newObj2 = Object.assign({}, obj);
    
    console.log(newObj2);

    可以把它封装成一个方法:

    // 封装成方法
    //
    返回一个新的变量副本 // get a copy of an object function getNewObjectOf(src) { return Object.assign({}, src); }

    缺点:

    1. 这个也是浅复制(仅复制顶层的属性,底层属性并不复制)。深层属性会同样返回索引,与原变量分享一个地址。(看下面栗子)

    let obj = {
      a: 1,
      b: {
        c: 2,
      },
    }
    let newObj = Object.assign({}, obj);
    console.log(newObj); // { a: 1, b: { c: 2} }
    
    obj.a = 10;
    console.log(obj); // { a: 10, b: { c: 2} }
    console.log(newObj); // { a: 1, b: { c: 2} }
    
    newObj.a = 20;
    console.log(obj); // { a: 10, b: { c: 2} }
    console.log(newObj); // { a: 20, b: { c: 2} }
    
    newObj.b.c = 30;
    console.log(obj); // { a: 10, b: { c: 30} }
    console.log(newObj); // { a: 20, b: { c: 30} }
    
    // 注意: 所有变量 的 *。b.c 都等于30; 原因看上面解释。

    结论:

    原文中还有很多其他的办法,但此文仅摘抄出最有用的几个。一般不会用到第一种办法,如需要复制的变量有很多层的话,需要用第二种办法来复制,如果变量仅仅包含一层(如json格式的配置信息变量),第三种是最高效的。

    再次给出封装好的方法:

    // 封装成方法
    // 返回一个新的变量副本 // get a copy of an object function getNewObjectOf(src) { return Object.assign({}, src); }

     

  • 相关阅读:
    MVC ORM 架构
    Kubernetes 第八章 Pod 控制器
    Kubernetes 第七章 Configure Liveness and Readiness Probes
    Kubernetes 第六章 pod 资源对象
    Kubernetes 第五章 YAML
    Kubernetes 核心组件
    Kubernetes 架构原理
    Kubernetes 第四章 kubectl
    Kubernetes 第三章 kubeadm
    yum 配置及yum 源配置
  • 原文地址:https://www.cnblogs.com/AndrewXu/p/11601285.html
Copyright © 2011-2022 走看看