2016-09-13 43 views
-1

需要帮助创建执行反向浅拷贝的自定义对象类型?例如:如何将浅拷贝一个javascript数组(容器)?

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

jQuery的延伸或(....) { arr[i] = deepcopy(arr[i]); }返回一个新的数组对象具有相同的长度,并且该新的数组的每个索引持有新/复制该同一索引处具有相同的键/值作为对象的对象原来的arrayobj。

你能帮助我建立构造,可以返回参考同一阵列容器,但每个插槽一个新的/复制的对象?理想的情况下可以强制突变限制不允许推/不印字/弹出/反向/移位/排序/剪接

然而,数组和阵列状物体之间的一个主要区别是,阵列状物体从Object.prototype中,而不是继承Array.prototype。这意味着类似于数组的对象无法访问常见的数组原型方法。

用例与原始数组对象的状态有关。因此,如果父阵列容器是一种状态,位于各指标的子对象将每个按键相同,但每个按键可以在比如果父阵列容器被认为是处于不同的状态不同的属性值进行设定。另外,保留原始数组的长度非常重要 - 只需根据原始数组的不同状态来担心每个插槽中的“行为”。

非常感谢您的宝贵意见和指导。

+2

*“[] .concat(arrayobj)或arrayobj.concat([])返回与相同长度的新的数组对象和这种新的数组的每个索引持有新的/重复的对象“*这是不正确的。它与使用'.slice'具有相同的结果。您正在寻找一个简单的'for'循环来迭代数组中的每个元素,克隆它并将其分配回相同的位置。克隆对象不是内置于JavaScript中。请参阅[在JavaScript中深入克隆对象的最有效方法是什么?](http://stackoverflow.com/q/122102/218196) –

+0

我认为这里真正的问题是“如何创建对象的副本?” – mhodges

+1

@FelixKling https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice“slice()方法返回一个数组的一部分到一个新数组的浅表副本object ...对于对象引用(而不是实际对象),slice将对象引用复制到新数组中。原始数组和新数组引用同一个对象。如果引用的对象更改,则更改对于新的和原始的阵列“。 –

回答

3

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

正如我在评论中提到的,一个简单的for循环会为你做的(假设你已经有了另一种机制,以深拷贝的对象):

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

downvote的原因是什么? –

1

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

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

但是,如果你想有通过保持不使参照对应的一个源阵列则可能做如纯JS如下在浅对象项的索引关系复制的对象的阵列;

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);

对于深对象转介,你需要自己的嵌套对象将Object.assign()工作的工具。

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] 
1

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

稍微扩展下面的代码将做你需要的东西。

// 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'); 
 
}