26
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-03-21

検証の背景

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

26
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?