使用传播语法在ES6中进行深层复制 [英] Deep copy in ES6 using the spread syntax

查看:126
本文介绍了使用传播语法在ES6中进行深层复制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为Redux项目创建一个深层副本映射方法,该方法将使用对象而不是数组.我了解到,在Redux中,每个状态都不应更改以前的状态.

I am trying to create a deep copy map method for my Redux project that will work with objects rather than arrays. I read that in Redux each state should not change anything in the previous states.

export const mapCopy = (object, callback) => {
    return Object.keys(object).reduce(function (output, key) {

    output[key] = callback.call(this, {...object[key]});

    return output;
    }, {});
}

有效:

    return mapCopy(state, e => {

            if (e.id === action.id) {
                 e.title = 'new item';
            }

            return e;
        })

但是它不能深度复制内部项目,因此我需要对其进行调整:

However it does not deep copy inner items so I need to tweak it to:

export const mapCopy = (object, callback) => {
    return Object.keys(object).reduce(function (output, key) {

    let newObject = {...object[key]};
    newObject.style = {...newObject.style};
    newObject.data = {...newObject.data};

    output[key] = callback.call(this, newObject);

    return output;
    }, {});
}

这不太优雅,因为它需要知道传递了哪些对象. ES6中是否有一种方法可以使用传播语法来深度复制对象?

This is less elegant as it requires to know which objects are passed. Is there a way in ES6 to use the spread syntax to deep copy an object?

推荐答案

ES6没有内置此类功能.我认为您可以根据自己的选择进行选择.

No such functionality is built-in to ES6. I think you have a couple of options depending on what you want to do.

如果您真的想深复制:

  1. 使用图书馆.例如,lodash具有 cloneDeep 方法.
  2. 实现您自己的克隆功能.

特定问题的替代解决方案(无深度复制)

但是,我认为,如果您愿意更改几件事,则可以节省一些工作.我假设您控制了函数的所有调用站点.

Alternative Solution To Your Specific Problem (No Deep Copy)

However, I think, if you're willing to change a couple things, you can save yourself some work. I'm assuming you control all call sites to your function.

  1. 指定所有传递给mapCopy的回调必须返回新对象,而不是对现有对象进行突变.例如:

  1. Specify that all callbacks passed to mapCopy must return new objects instead of mutating the existing object. For example:

mapCopy(state, e => {
  if (e.id === action.id) {
    return Object.assign({}, e, {
      title: 'new item'
    });
  } else {  
    return e;
  }
});

这利用了 Object.assign 创建一个新对象,在该新对象上设置e的属性,然后在该新对象上设置一个新标题.这意味着您永远不会突变现有对象,而仅在必要时创建新对象.

This makes use of Object.assign to create a new object, sets properties of e on that new object, then sets a new title on that new object. This means you never mutate existing objects and only create new ones when necessary.

mapCopy现在可以非常简单:

export const mapCopy = (object, callback) => {
  return Object.keys(object).reduce(function (output, key) {
    output[key] = callback.call(this, object[key]);
    return output;
  }, {});
}

从本质上讲,mapCopy相信其调用者可以做正确的事情.这就是为什么我说这假设您控制所有呼叫站点.

Essentially, mapCopy is trusting its callers to do the right thing. This is why I said this assumes you control all call sites.

这篇关于使用传播语法在ES6中进行深层复制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆