JavaScriptでオブジェクトをdeep copyする方法

プログラミング

JavaScriptにもJavaやC#と同じように参照型変数が存在し、オブジェクトや配列、関数が参照型変数です。
そして、JavaやC#と同じように、単純に「=」で代入するだけでは参照先(オブジェクトのメモリ領域を示すポインタ)しかコピーできず、コピー先の変更がコピー元に影響してしまいますし、その逆にコピー元の変更がコピー先に影響してしまいます。
(このようなコピーを「シャローコピー(浅いコピー)」と呼びます)

これを避けたい場合には、参照しているメモリの中身を丸ごとコピー(新たにメモリ領域を確保し書き込み)する必要があります。 (このようなコピーを「ディープコピー(深いコピー)」と呼びます)
JavaScriptでは標準でディープコピーを行うための関数が用意されていないので、自力で実装するか、外部のライブラリを使用するかする必要があります。
今回は、deepcopyというライブラリを使用します。
(なお、ディープコピーをサポートするライブラリは他にもあり、用途に応じて使い分けた方が良いです。JSONでシリアライズ・デシリアライズする方法もありますが、関数やundefinedがコピーされない等の問題があるので注意が必要です。)

以下、サンプルコードです。
Node.jsを使用して検証します。

【事前準備】

・Node.js command prompt を起動

・作業フォルダ(今回は”C:\tmp\”)に移動

・deepcopyライブラリをインストール

【サンプルコード】

サンプルコードは作業フォルダ直下に作成します。

・ShallowCopy.js

・DeepCopy.js

実行結果】


いかがでしたでしょうか?

JavaScriptのディープコピーは実務でも誤りやすいポイントであり、関数が含まれるオブジェクトをJSONのシリアライズ・デシリアライズでディープコピーしてしまいバグになる所を実際に目にしたこともあります。
ディープコピーの方法は今回紹介した方法以外にも色々あるので、現場毎で確認すると良いでしょう。

コメント

タイトルとURLをコピーしました