検証の背景
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
やってみる
ディープコピーと、比較でシャローコピーもやってみます。
ソースコード
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' } }
所感
思いのほか簡単でびっくりしましたが、
そもそも速度性能やコストを考えると、
ディープコピーをしないような作りにしたほうがいいと思います。
とはいえ、使わざる得ない局面ではかなり役に立ちそうですね!!