当我创建一个数组包含对象时,新数组仍然具有对初始数组中对象的引用。如何使用对象副本制作切片?
var obj1 = {name: 'object1'};
var obj2 = {name: 'object2'};
var array = [obj1, obj2];
var arraySlice = array.slice(0, 1);
arraySlice[0].name = 'object1RENAMED';
console.log(array[0].name);
console.log(arraySlice[0].name);
打印:
object1RENAMED
object1RENAMED
答案 0 :(得分:1)
在我们的例子中,您对值(值是对象)具有相同的引用,这就是为什么您可以更改不同数组中的值的原因。您需要创建一个深度克隆/副本:
var arraySlice = JSON.parse(JSON.stringify(array.slice(0, 1)));
如果您使用jQuery,您可以这样做
var arraySlice = $.extend(true, [], array.slice(0, 1));
答案 1 :(得分:1)
您正在制作数组的浅表副本,而不是深层副本,因此两个数组仍然引用相同的对象。您还需要克隆对象。
var arraySlice = JSON.parse(JSON.stringify(array.slice(0, 1)));
我从
获取了这个克隆代码What is the most efficient way to deep clone an object in JavaScript?
答案 2 :(得分:0)
这是一个递归功能(cloneObj
),可以让您的生活更轻松。它使用Array.map
来克隆所有级别Array
内的对象。
var array = [{name: 'object1'}, {name: 'object2'}];
Helpers.log2Screen('array initially:<br>'+Object.print(array));
var arraySlice = cloneObj(array);
// change names in clone:
arraySlice[0].name = "changed";
arraySlice[1].name = "DEMO";
arraySlice[1].addedProp = [{a: 1, b: 2}, {a: 2, b:3}];
Helpers.log2Screen('arraySlice (clone, changed):<br>'+Object.print(arraySlice));
Helpers.log2Screen('array didn\'t change, still:<br>'+Object.print(array));
function cloneObj(obj) {
// clone the whole enchillada, recursive
function clone(o, curr) {
for (var l in o){
if (!o.hasOwnProperty(l)) { continue; }
if (o[l] instanceof Object) {
curr[l] = cloneObj(o[l]);
} else {
curr[l] = o[l];
}
}
return curr;
}
return obj instanceof Array
? obj.slice().map( function (v) { return cloneObj(v); } )
: obj instanceof Date
? new Date(obj.getTime())
: obj instanceof Object
? clone(obj, {})
: obj;
}
&#13;
<script src="https://rawgit.com/KooiInc/Helpers/master/Helpers-min.js"></script>
&#13;