JavaScript
Node.js

javascriptでlodashを使ってディープコピーを簡単に行う


検証の背景

Javascriptでオブジェクトなどを含む、

ディープコピーがうまくできない問題が話題になります。

そのあたりは下記サイト様をご参照ください。

ES6のObject.assignがシャローコピーなのでディープコピーする方法を考える

[JavaScript]色々なディープコピー

JavaScript:Array,Object,Map,Set,Dateをまとめてディープコピーする

Node.jsのnpmで、

簡単にディープコピーができるものがあったので、

紹介します。


環境

node.js v8.12.0

npm v6.4.1


ライブラリを取得する

$ npm install lodash

lodashというライブラリは、

配列、オブジェクト、文字列を簡単に扱えるようになる、

人気のライブラリだそうです。

詳しくは下記公式サイトをご確認ください。

github

npm

なおブラウザでも使えるようです。(未検証)

https://www.jsdelivr.com/package/npm/lodash


やってみる

ディープコピーと、比較でシャローコピーもやってみます。


ソースコード


index.js

const clone = require('lodash/clone');

const clonedeep = require('lodash/cloneDeep');

// まずオリジナルを定義する
const externalObject = {
color: 'red'
};
const original = {
a: new Date(),
b: NaN,
c: new Function(),
d: undefined,
e: function () { },
f: Number,
g: false,
h: Infinity,
i: externalObject
};

// シャローコピー
const cloned = clone(original);

// 1階層したのオブジェクトの値を変える
// ※オリジナルのほうだけのつもり
externalObject.color = 'blue';

// iの中身が変わってしまう
console.log('***original ----------------- shallow copy');
console.log(original);
console.log('***cloned ------------------- shallow copy');
console.log(cloned); // 両方blueになる。。。

// ディープコピー
const deepcloned = clonedeep(original);
externalObject.color = 'yellow';

// iの中身が変わらない!!!
console.log('\n***original ------------------ deep copy');
console.log(original); // オリジナルだけyellowになってる
console.log('***deepcloned ---------------- deep copy');
console.log(deepcloned); // blueのまま!



実行

$ node index.js

***original ----------------- shallow copy
{ a: 2019-03-21T17:48:35.494Z,
b: NaN,
c: [Function: anonymous],
d: undefined,
e: [Function: e],
f: [Function: Number],
g: false,
h: Infinity,
i: { color: 'blue' } }
***cloned ------------------- shallow copy
{ a: 2019-03-21T17:48:35.494Z,
b: NaN,
c: [Function: anonymous],
d: undefined,
e: [Function: e],
f: [Function: Number],
g: false,
h: Infinity,
i: { color: 'blue' } }

***original ------------------ deep copy
{ a: 2019-03-21T17:48:35.494Z,
b: NaN,
c: [Function: anonymous],
d: undefined,
e: [Function: e],
f: [Function: Number],
g: false,
h: Infinity,
i: { color: 'yellow' } }
***deepcloned ---------------- deep copy
{ a: 2019-03-21T17:48:35.494Z,
b: NaN,
c: [Function: anonymous],
d: undefined,
e: [Function: e],
f: [Function: Number],
g: false,
h: Infinity,
i: { color: 'blue' } }


所感

思いのほか簡単でびっくりしましたが、

そもそも速度性能やコストを考えると、

ディープコピーをしないような作りにしたほうがいいと思います。

とはいえ、使わざる得ない局面ではかなり役に立ちそうですね!!


参考

How to deep clone a JavaScript object

stackOverflow