如何反转浅层复制javascript数组(容器)?

时间:2016-09-13 22:47:44

标签: javascript arrays shallow-copy

需要帮助创建执行反向浅拷贝的自定义对象类型吗?例如:

arrayobj.slice(0)返回一个具有相同长度的新数组对象,但每个索引都维护对在原始arrayobj的相同索引处找到的对象的引用。所以没有重复的对象

jQuery的扩展或(....) { arr[i] = deepcopy(arr[i]); }返回一个具有相同长度的新数组对象,并且这个新数组的每个索引都包含一个新的/重复的对象,其具有与该对象相同的键/值。原始arrayobj的索引相同。

你能帮我创建一个可以返回对同一个数组容器的引用的构造,但是在每个槽中都是一个新的/重复的对象吗?理想情况下可以强制实施突变限制,禁止推/非移位/弹出/反向/移位/排序/拼接

  

然而,Arrays和类似Array的对象之间的一个关键区别是类似Array的对象继承自Object.prototype而不是Array.prototype。这意味着类似数组的对象无法访问常见的数组原型方法。

用例与原始数组对象的状态有关。因此,如果父数组容器处于一种状态,则位于每个索引中的子对象将各自具有相同的键,但是每个键可以设置为与发现父数组容器处于不同状态时不同的属性值。另外,保留原始阵列的长度很重要 - 只是担心"行为"在每个插槽中根据原始数组的不同状态。

提前感谢您的见解和指导。

4 个答案:

答案 0 :(得分:3)

  

是否有一个构造可以返回对同一个数组容器的引用,但每个槽中都有一个新的/重复的对象?

正如我在评论中提到的,一个简单的for循环将为您做到这一点(假设您已经有另一种机制来深度复制对象):

for (var i = 0; i < arr.length; i++) {
  arr[i] = deepcopy(arr[i]);
}

答案 1 :(得分:1)

  

是否有可以返回对同一数组的引用的构造   容器,但在每个插槽中是一个新的/重复的对象?

不,我不这么认为。引用同一个数组容器的两个单独的值保证了数组与它的内容一样是同一个数组。

但是,如果您希望通过维护索引关系来复制对象数组,而不使浅层对象项引用源数组中的相应对象项,那么您可以在纯JS中执行以下操作;

&#13;
&#13;
var arr = [{a:1},{b:2}],
    brr = arr.map(o => Object.assign({},o));
console.log(arr);
console.log(brr);
arr[0].a = 3;
brr[1].b = 4;
console.log(arr);
console.log(brr);
&#13;
&#13;
&#13;

对于深层对象引用,您需要一个自己在嵌套对象上应用Object.assign()个作业的工具。

答案 2 :(得分:1)

这是你在寻找什么

var a=['asda','sdf','sdfsdfsdf'];
var b = {};
for(var i=0; i<a.length;i++){
   b[i]=JSON.parse(JSON.stringify(a[i]));
}

console.log(Object.prototype.toString.call(a)); //[Object array]

console.log(Object.prototype.toString.call(b)); // [Object object]

答案 3 :(得分:1)

您可以使用Proxy。这是一个创新的东西,JS世界尚未得到广泛支持,但旨在解决像你一样的问题

在代码之后稍加扩展就可以完成您需要的任务。

&#13;
&#13;
// base array to extend
let base = [1, 2, 3, 4, 5];

// array of values which will replace values in original array
let extention = [, 12, , 14,];

let prohibitedMethods = ['push'];

let proxiedArray = new Proxy(base, {
  get (target, key) {
    console.info(`# Get on property "${key}"`)
    if (prohibitedMethods.indexOf(key) != -1) {
        throw new Error('Prohibited');
    }
    return extention[key] ? extention[key] : target[key];
  }
});

for(var i = 0; i < proxiedArray.length; i++) {
    // will write 1, 12, 3, 14, 5
    // as you can see part of the values taken from `extention` array
    console.log(proxiedArray[i])
}

try {
    proxiedArray.push(1);
} catch(e) {
    console.log('Cannot push! and that\'s great');
}
&#13;
&#13;
&#13;