使用扩展语法在 ES6 中进行深度复制 [英] Deep copy in ES6 using the spread syntax

查看:37
本文介绍了使用扩展语法在 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天全站免登陆