JavaScriptオブジェクトのクローンを作成する方法

JavaScriptはオブジェクトをコピーする多くの方法を提供しますが、すべてがディープコピーを提供するわけではありません。最も効率的な方法を学び、またあなたが持っているすべてのオプションを見つけてください

JavaScriptでオブジェクトをコピーするのは難しい場合があります。いくつかの方法は浅いコピーを実行します。これはほとんどの場合のデフォルトの動作です。

深いコピーと浅いコピー

浅いコピーは正常にコピーしますプリミティブ型数字や文字列と同様ですが、オブジェクト参照は再帰的にコピーされませんが、代わりに、新しくコピーされたオブジェクトは同じオブジェクトを参照します。

オブジェクトが他のオブジェクトを参照している場合、浅いコピーオブジェクトの、あなた参照をコピーする外部オブジェクトに。

実行するときディープコピー、それら外部オブジェクトもコピーされますしたがって、新しいクローンオブジェクトは古いオブジェクトから完全に独立しています。

インターネット上のJavaScriptでオブジェクトをディープクローンする方法を検索すると、多くの答えが見つかりますが、答えは常に正しいとは限りません

最も簡単なオプション:Lodashを使用する

ディープコピーを実行するための私の提案は、十分にテストされ、非常に人気があり、注意深く保守されているライブラリであるLodashに依存することです。

Lodashは非常に便利ですcloneそしてdeepclone浅いおよび深いクローニングを実行する機能。

Lodashには次の優れた機能があります。単一の関数を個別にインポートできますプロジェクトで、依存関係のサイズを大幅に削減します。

Node.jsの場合:

const clone = require('lodash.clone')
const clonedeep = require('lodash.clonedeep')

使用中のこれら2つの関数を示す例を次に示します。

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)

externalObject.color = ‘blue’

console.info(‘⬇️ shallow cloning 🌈’) console.info( ‘✏️ Notice the i.color property we changed on original is also changed in the shallow copy’ ) console.log(original) console.log(cloned)

const deepcloned = clonedeep(original)

externalObject.color = ‘yellow’ console.log(’’) console.info(‘⬇️ deep cloning 🌈’) console.info(‘✏️ Notice the i.color property does not propagate any more’) console.log(original) console.log(deepcloned)

この簡単な例では、最初に浅いコピーを作成し、コピーされたオブジェクトに伝播するi.colorプロパティを編集します。

ディープクローンでは、これは発生しません。

Object.assign()

Object.assign()ディープクローンではなく、オブジェクトのシャローコピーを実行します。

const copied = Object.assign({}, original)

浅いコピーであるため、値が複製され、オブジェクト参照がコピーされます(オブジェクト自体ではありません)。したがって、元のオブジェクトでオブジェクトプロパティを編集すると、参照される内部オブジェクトが同じであるため、コピーされたオブジェクトでも変更されます。

const original = {
  name: 'Fiesta',
  car: {
    color: 'blue',
  },
}
const copied = Object.assign({}, original)

original.name = ‘Focus’ original.car.color = ‘yellow’

copied.name //Fiesta copied.car.color //yellow

オブジェクトスプレッド演算子の使用

ザ・スプレッド演算子ES6 / ES2015浅いクローンを実行するための非常に便利な方法を提供する機能。Object.assign()します。

const copied = { ...original }

間違った解決策

オンラインでは、多くの提案が見つかります。ここにいくつかの間違ったものがあります:

Object.create()の使用

注:推奨されません

const copied = Object.create(original)

これは間違っています。コピーを実行していません。

代わりに、originalオブジェクトはとして使用されていますプロトタイプcopied

どうやらそれは機能しますが、内部ではそうではありません:

const original = {
  name: 'Fiesta',
}
const copied = Object.create(original)
copied.name //Fiesta

original.hasOwnProperty('name') //true
copied.hasOwnProperty('name') //false

詳細はこちらObject.create()

JSONシリアル化

注:推奨されません

に変換することをお勧めする人もいますJSON

const cloned = JSON.parse(JSON.stringify(original))

しかし、それは予期しない結果をもたらします。

これを行うことにより、あなたは失うJSONに同等のタイプがないJavascriptプロパティFunctionまたはInfinity。に割り当てられているすべてのプロパティundefinedによって無視されますJSON.stringify、クローンオブジェクトでそれらが失われる原因になります。

また、たとえばDateオブジェクト(タイムゾーンを考慮せず、デフォルトでUTCに設定されている)、Set、Mapなど、一部のオブジェクトは文字列に変換されます。

JSON.parse(
  JSON.stringify({
    a: new Date(),
    b: NaN,
    c: new Function(),
    d: undefined,
    e: function () {},
    f: Number,
    g: false,
    h: Infinity,
  })
)

Parsing as JSON

これは、内部オブジェクトと関数がなく、値のみがある場合にのみ機能します。

私の無料ダウンロードJavaScriptビギナーズハンドブック


その他のjsチュートリアル: