【JavaScript】オブジェクトや配列のコピーを作成する
JavaScriptでオブジェクトや配列を別の変数に渡した場合、値ではなく参照のコピーが行われます。
そのため、コピー先に変更があった場合にはコピー元の値も変わってしまいます。
(function(){ var srcObj; var copyObj; // コピー元を作成する srcObj = {}; srcObj.val = 'A'; // コピー先のオブジェクトを作成する copyObj = srcObj; copyObj.val = 'B'; // コピー元 console.log('src.val : ' + srcObj.val); // B // コピー先 console.log('copy.val : ' + copyObj.val); // B })();
上の例はオブジェクトですが、配列でも同じことが起こります。
調べてみると、配列の場合はsliceを使って簡単にコピーが出来る、というのが見つかります。
(function(){ var srcArray; var copyArray; // コピー元を作成する srcArray = new Array(); srcArray.push('A'); // コピー先のオブジェクトを作成する copyArray = srcArray.slice(0, srcArray.length); copyArray[0] = 'B'; // コピー元 console.log('srcArray[0] : ' + srcArray[0]); // A // コピー先 console.log('copyArray[0] : ' + copyArray[0]); // B })();
しかし、配列内にオブジェクトが存在すると、この方法でも参照渡しになります。
(function(){ var obj; var srcArray; var copyArray; // オブジェクトを作成する obj = {}; obj.val = 'A'; // コピー元を作成する srcArray = new Array(); srcArray.push(obj); // コピー先のオブジェクトを作成する copyArray = srcArray.slice(0, srcArray.length); copyArray[0].val = 'B'; // コピー元 console.log('srcArray[0].val : ' + srcArray[0].val); // B // コピー先 console.log('copyArray[0].val : ' + copyArray[0].val); // B })();
これらはオブジェクトや配列としてコピーするから参照が渡されるわけです。
つまり、オブジェクトや配列としてコピーしなければ良いわけですね。
一度文字列に変換し、その文字列から復元すればどうでしょうか。
(function(){ var obj; var srcArray; var copyArray; var jsonArray; // オブジェクトを作成する obj = {}; obj.val = 'A'; obj.func = function(){console.log('funcA');}; // コピー元を作成する srcArray = new Array(); srcArray.push(obj); // JSON文字列に変換する jsonArray = JSON.stringify(srcArray); // JSON文字列から配列を復元する copyArray = JSON.parse(jsonArray); copyArray[0].val = 'B'; copyArray[0].func = function(){console.log('funcB');}; // コピー元 console.log('srcArray[0].val : ' + srcArray[0].val); // A // コピー先 console.log('copyArray[0].val : ' + copyArray[0].val); // B srcArray[0].func(); // funcA copyArray[0].func(); // funcB })();
値がコピーされているかと思います。
変数にfunctionなんかもコピーされるようです。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
No comments.