为什么深度复制在JS(或不是)中表现不同?

时间:2018-03-17 17:21:03

标签: javascript jquery oop

来自C ++背景,以及JS的新手,我想做一个对象的深层复制。

这是我想用OOP语言做的事情(仍在学习JS语言)。

我将foo类的虚拟对象传递给doSomething类的构造函数。

每当doSomething需要对foo做一些事情时,它会深度复制虚拟foo对象,自定义它并将新副本存储到数组中。

foo对象数组中应该有不同的foo对象。但是,存储在数组中的所有对象都“引用”处理的最后一个foo对象。

在我看来,它存储了对虚拟对象的引用。

我尝试了帖子中提出的方法 What is the most efficient way to deep clone an object in JavaScript? ,但没有得到我想要的。我在下面的代码示例中使用_.cloneDeep()作为示例。

========================= code ===================== ==

我有一个foo.js

define(["jquery", "react", "react-dom", "react-components"], 
function($, React, ReactDOM, ReactComponents) {
  "use strict";

  function foo(x, y, z) {
    var $x = x,
        $y = y,
        $z = z;

    function f1 () {}
    function f2 () {}
    function setX(x) {}
    function setY(y) {}
    function whichFoo() {//prints to the console to identify which object it is}

    return {
      f1: f1,
      f2: f2,
      setX: setX,
      setY: setY,
      whichFoo: whichFoo
    };
  }

  return foo;
});

我有一个创建foo的index.html并将其传递给doSomething.js:

<script>
require(['doSomething', 'foo'], function(doSomething, foo) {
  var aFoo = foo(null, null, null);
  doSomething(aFoo);
}
</script>

这是doSomething.js:

define([various libraries], function(various libraries) {
  "use strict";
  function doSomething(aFoo) {

    var dummyFoo = _.cloneDeep(aFoo), // I understand aFoo is a reference so deepcopy it here to create a different object.
        fooList = [];

    // other functions; 

    function run() {
      // an object of ids is created here.
      _.each(ids, callback);
    }

    function callback(k, v) {
      var newX = getX(v),
          newY = getY(v);

      var newFoo = _.cloneDeep(dummyFoo); // creates a copy of object for customization
      // customize newFoo
      newFoo.setX(newX);
      newFoo.setY(newY);

      newFoo.whichFoo(); //verified different foo each time.

      fooList.push(newFoo);
    }

    function loopFooList() {
      for (var i = 0; i < fooList.length; i++) {
        fooList[i].whichFoo(); // every item in the list references the foo created in the last callback...
      }
    }
    return {...};
  }
  return doSomething;
}

根据我的理解,_.cloneDeep()在不同的内存位置创建一个克隆的对象的新对象,并返回对新对象的引用。所以即使fooList存储引用(不是实际对象),它们也应该引用它们各自的对象,为什么最终它们引用最后创建的对象?

我觉得JS意义上的深度复制不同于C ++。任何人都可以告诉我为什么我的代码没有按照预期的方式工作,并指出JS在实现我想要的方式(深度复制C ++意义上的对象)?

PS:我之所以使用这种奇怪的自定义虚拟对象的方法,而不是每次需要时都在doSomething中创建foo的新实例,是因为我需要避免使用doSomething加载反应组件,这会导致测试中超时(但它没有加载index.html进行测试),我无法改变。

所以这是一个黑客:)但它不会影响深层复制的结果。

0 个答案:

没有答案