Search code examples
javascriptecmascript-6lodashes6-proxy

lodash cloneDeep remove proxy from object


When I deep clone proxy object then it returns a normal object without proxy. but i want proxy object when i deep clone object.

EX:

class Abc {
  constructor() {
    this.a = 4;
    return new Proxy(this, {
      get(target, name) {
        return target[name];
      },
    });
  }
}

class Xyz {
  constructor() {
    this.x = new Abc();
    this.y = _.cloneDeep(this.x);
  }
}

var proxyObject = new Xyz().x;
var normalObject = new Xyz().y;
console.log(proxyObject); // Type Proxy
console.log(normalObject); // Type Object

Is there any way to clone deep object like original object behavior like this.x


Solution

  • I don't know of any simple (straightforward) solution to this problem.

    One way to achieve this functionality is to modify your Abc constructor to include the original object itself (not the proxy) in a property (let's say orig).

    Then you can define your own copy method. When you invoke this method on a proxy object, it fetches the non-proxy object stored in orig property, performs lodash's cloneDeep and returns new proxy object created from this cloned object.

    class Abc {
      constructor(orig = this) {
        this.orig = orig;
        this.a = 4;
        this.arr = [1, 2];
        return new Proxy(this, {
          get(target, name) {
            return target[name];
          },
        });
      }
    
      copy() {
        const cloned = _.cloneDeep(this.orig);
        return new Proxy(cloned, {
          get(target, name) {
            return target[name];
          }
        });
      }
    }
    
    class Xyz {
      constructor() {
        this.x = new Abc();
        this.y = this.x.copy();
      }
    }
    
    var proxyObject = new Xyz().x;
    var normalObject = new Xyz().y;
    
    console.log(proxyObject); 
    console.log(normalObject);
    
    proxyObject.arr.push(3);
    
    console.log(proxyObject.arr);
    console.log(normalObject.arr);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>

    Now both the proxyObject and normalObject are proxies and we can also see that the proxy object was indeed copied because after running proxyObject.arr.push(3) the normalObject's arr stays unchanged.