【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.