关于javascript:Object.assign保持对原始对象的引用

Object.assign keeps reference to original object

本问题已经有最佳答案,请猛点这里访问。

我有办法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
export const groupActivities = ({ activities, tags, images, tickets }) => {
  if (!activities || !tags) {
    console.error('Must have activities and tags');
  }

  const groupActivities = Object.assign({}, activities);

  const groups = groupByTags({ activities: groupActivities, tags });

  groups.forEach(group => {
    group.length = group.activities.length;
    console.log(group.length);
    group.activities.forEach(activity => {
      if (images) {
        activity.images = activity.imageIds.map(id => images[id]);
      }

      if (tickets) {
        console.warn('No tickets provided to the groupactivities helper. May cause problems.');
        activity.tickets = activity.ticketIds.map(id => tickets[id]);
      }
    });
  });

  return groups;
};

object.assign正在复制activities对象,但仍然保留对它的引用,因此如果我找到一个特定的活动并更改它的某些属性,它也会更改原始的活动!(更改GroupActivities['someID'].name='name'更改Activities对象上的相应活动!)

这导致了一些奇怪的虫子。有什么解决办法吗?

使用babel 5进行编译。


事实上,这可以通过不同的方式实现:

  • 如果不需要外部导入,则实现自己的,但要考虑嵌套对象。我实现了我自己的如下(如果您有一个需要深度克隆的嵌套对象,那么设置deep=true):
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    function cloneObj(obj, deep=false){
      var result = {};
      for(key in obj){
        if(deep && obj[key] instanceof Object){
           if(obj[key] instanceof Array){
             result[key] = [];
             obj[key].forEach(function(item){
                if(item instanceof Object){
                   result[key].push(cloneObj(item, true));
                } else {
                   result[key].push(item);
                }
             });
           } else {
             result[key] = cloneObj(obj[key]);
           }
        } else {
           result[key] = obj[key];
        }
      }
      return result
    }


    // Shallow copy
    var newObject = cloneObj(oldObject);
    // Deep copy
    var newObject = cloneObj(oldObject, true);
  • 使用jQuery:
  • 1
    2
    3
    4
    5
    // Shallow copy
    var newObject = jQuery.extend({}, oldObject);

    // Deep copy
    var newObject = jQuery.extend(true, {}, oldObject);
  • 使用下划线:
  • 1
    2
     // Shallow copy
     var newObject = _.clone(oldObject);

    PS:我用以下数据测试了我的功能,运行良好:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var oldObject = {a:1, b:{d:2,c:6}, c:[1,2,{t:1}]};
    newObject= cloneObj(oldObject, true);

    newObject['b']['d']=8;
    newObject['a']=8;
    newObject['c'][2]['t']=5;


    console.log(oldObject)
    console.log(newObject)