1. ホーム
  2. javascript

[解決済み] ES6でのスプレッドシンタックスによるディープコピー

2022-08-08 01:31:30

質問

私は自分のReduxプロジェクトで、配列ではなくオブジェクトで動作するディープコピーマップメソッドを作成しようとしています。私はReduxで各状態が前の状態で何も変更してはいけないと読みました。

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;
        })

しかし、これは内側の項目を深くコピーしないので、私はそれを調整する必要があります。

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では、オブジェクトをディープコピーするためにスプレッドシンタックスを使用する方法はあるのでしょうか?

どのように解決するのですか?

ES6にはそのような機能は組み込まれていません。やりたいことに応じて、いくつかの選択肢があると思います。

本当にディープコピーしたいのなら

  1. ライブラリを使う。例えば、lodashには cloneDeep というメソッドがあります。
  2. 独自のクローン機能を実装する。

特定の問題に対する代替ソリューション (ディープ コピーなし)

しかし、いくつかの点を変更することをいとわないのであれば、いくつかの作業を省くことができると思います。私は、あなたが関数へのすべての呼び出しサイトを制御していると仮定しています。

  1. に渡される全てのコールバックが mapCopy に渡される全てのコールバックは、既存のオブジェクトを変異させるのではなく、 新しいオブジェクトを返さなければなりません。例えば

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

    これは Object.assign を使用して新しいオブジェクトを作成し、そのオブジェクトのプロパティを e のプロパティを設定し、その新しいオブジェクトに新しいタイトルを設定します。つまり、既存のオブジェクトを決して変異させず、必要なときだけ新しいオブジェクトを作成するのです。

  2. mapCopy はもう本当にシンプルでいいんです。

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

本来は mapCopy はその呼び出し元が正しいことをするのを信頼しています。これが、すべてのコール サイトを制御していることを前提に述べた理由です。