Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
22
Help us understand the problem. What is going on with this article?
@t-motoki

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

More than 1 year has passed since last update.

検証の背景

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

22
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
t-motoki
UXデザイナーを目指しています。 言語はNode.js、C++が好きです。Javaもやってます。 ネットワークインフラも少しやってます。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
22
Help us understand the problem. What is going on with this article?