JS: Does Object.assign() create deep copy or shallow copy

后端 未结 7 1086
粉色の甜心
粉色の甜心 2020-11-30 03:21

I just came across this concept of

var copy = Object.assign({}, originalObject);

which creates a copy of original object into the \"

相关标签:
7条回答
  • 2020-11-30 04:06

    It creates a shallow copy, according to this paragraph from MDN:

    For deep cloning, we need to use other alternatives because Object.assign() copies property values. If the source value is a reference to an object, it only copies that reference value.

    For the purposes of redux, Object.assign() is sufficient because the state of a redux app only contains immutable values (JSON).

    0 讨论(0)
  • 2020-11-30 04:06

    For small Data structures I see that JSON.stringify() and JSON.parse() work nice.

    // store as JSON
    var copyOfWindowLocation = JSON.stringify(window.location)
    console.log("JSON structure - copy:", copyOfWindowLocation)
    // convert back to Javascript Object
    copyOfWindowLocation = JSON.parse(copyOfWindowLocation)
    console.log("Javascript structure - copy:", copyOfWindowLocation)
    
    0 讨论(0)
  • 2020-11-30 04:07
    var copy = Object.assign({}, originalObject);
    

    does a shallow copy which is changing the copy reflect changes in your original object also. So to perform deep copy I would recommend the lodash cloneDeep

    import cloneDeep from 'lodash/cloneDeep';
    var copy = cloneDeep(originalObject);
    
    0 讨论(0)
  • 2020-11-30 04:10

    Forget about deep copy, even shallow copy isn't safe, if the object you're copying has a property with enumerable attribute set to false.

    MDN :

    The Object.assign() method only copies enumerable and own properties from a source object to a target object

    take this example

    var o = {};
    
    Object.defineProperty(o,'x',{enumerable: false,value : 15});
    
    var ob={}; 
    Object.assign(ob,o);
    
    console.log(o.x); // 15
    console.log(ob.x); // undefined
    
    0 讨论(0)
  • 2020-11-30 04:11

    As mentioned above, Object.assign() will do a shallow clone, fail to copy the source object's custom methods, and fail to copy properties with enumerable: false.

    Preserving methods and non-enumerable properties takes more code, but not much more.

    This will do a shallow clone of an array or object, copying the source's methods and all properties:

    function shallowClone(src) {
      let dest = (src instanceof Array) ? [] : {};
    
    // duplicate prototypes of the source
      Object.setPrototypeOf(dest, Object.getPrototypeOf(src));
    
      Object.getOwnPropertyNames(src).forEach(name => {
        const descriptor = Object.getOwnPropertyDescriptor(src, name);
        Object.defineProperty(dest, name, descriptor);
      });
      return dest;
    }
    

    Example:

    class Custom extends Object {
      myCustom() {}
    }
    
    const source = new Custom();
    source.foo = "this is foo";
    Object.defineProperty(source, "nonEnum", {
      value: "do not enumerate",
      enumerable: false
    });
    Object.defineProperty(source, "nonWrite", {
      value: "do not write",
      writable: false
    });
    Object.defineProperty(source, "nonConfig", {
      value: "do not config",
      configurable: false
    });
    
    let clone = shallowClone(source);
    
    console.log("source.nonEnum:",source.nonEnum);
    // source.nonEnum: "do not enumerate"
    console.log("clone.nonEnum:", clone.nonEnum);
    // clone.nonEnum: – "do not enumerate"
    
    console.log("typeof source.myCustom:", typeof source.myCustom);
    // typeof source.myCustom: – "function"
    console.log("typeof clone.myCustom:", typeof clone.myCustom);
    // typeof clone.myCustom: – "function"
    

    jsfiddle

    0 讨论(0)
  • 2020-11-30 04:14

    By using Object.assign(), you are actually doing Shallow Copy of your object. Whenever we do an operation like assigning one object to other, we actually perform a shallow copy, i.e. if OBJ1 is an object, modifying it through another object which is OBJ2 will reflect changes in OBJ1 too.

    0 讨论(0)
提交回复
热议问题