如何反向浅拷贝javascript数组(容器)?
需要帮助创建执行反向浅复制的自定义对象类型吗?例如:如何反向浅拷贝javascript数组(容器)?,javascript,arrays,shallow-copy,Javascript,Arrays,Shallow Copy,需要帮助创建执行反向浅复制的自定义对象类型吗?例如: arrayobj.slice(0)返回一个长度相同的新数组对象,但每个索引都保留对在原始arrayobj的相同索引中找到的对象的引用。所以没有重复的对象 jQuery的extend or for(..){arr[i]=deepcopy(arr[i]);}返回一个长度相同的新数组对象,该新数组的每个索引都包含一个新的/重复的对象,该对象与原始arrayobj的相同索引中的对象具有相同的键/值 您能帮我创建一个构造,它可以返回对同一数组容器的引用
arrayobj.slice(0)
返回一个长度相同的新数组对象,但每个索引都保留对在原始arrayobj的相同索引中找到的对象的引用。所以没有重复的对象
jQuery的extend or for(..){arr[i]=deepcopy(arr[i]);}
返回一个长度相同的新数组对象,该新数组的每个索引都包含一个新的/重复的对象,该对象与原始arrayobj的相同索引中的对象具有相同的键/值
您能帮我创建一个构造,它可以返回对同一数组容器的引用,但每个插槽中都有一个新的/重复的对象吗?理想情况下,可以强制突变限制,禁止推送/取消移位/弹出/反转/移位/排序/拼接
但是,数组和类数组对象之间的一个关键区别是类数组对象继承自Object.prototype,而不是Array.prototype。这意味着类似数组的对象无法访问常见的数组原型方法
用例与原始数组对象的状态相关。因此,如果父数组容器处于一种状态,则每个索引中的子对象都将具有相同的键,但每个键的属性值可能与发现父数组容器处于不同状态时的属性值不同。此外,保留原始阵列的长度也很重要—只需担心基于原始阵列不同状态的每个插槽中的“行为”
提前感谢您的洞察力和指导
是否有一个构造可以返回对同一数组容器的引用,但每个插槽中都有一个新的/重复的对象
正如我在评论中提到的,一个简单的for
循环将为您实现这一点(假设您已经有了另一种深度复制对象的机制):
for(变量i=0;i
是否存在可以返回对同一数组的引用的构造
容器,但每个插槽中都有一个新的/重复的对象
不,我不这么认为。引用同一数组容器的两个单独的值当然可以保证数组及其内容是同一个数组
但是,如果您希望通过维护索引关系复制对象数组,而不使浅层对象项引用源数组中的相应项,那么您可以在纯JS中执行以下操作:
var arr=[{a:1},{b:2}],
brr=arr.map(o=>Object.assign({},o));
控制台日志(arr);
控制台日志(brr);
arr[0].a=3;
brr[1].b=4;
控制台日志(arr);
控制台日志(brr)代码>这就是你要找的吗
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]
var a=['asda','sdf','sdfsdfsdf'];
var b={};
对于(var i=0;i您可以使用它。这是一个创新的东西,JS world尚未得到广泛支持,但旨在解决像您这样的问题
通过一点扩展,下面的代码将完成您需要的所有事情
//要扩展的基数组
设base=[1,2,3,4,5];
//将替换原始数组中的值的值数组
设扩张=[,12,14,];
让prohibitedMethods=['push'];
让proxiedArray=新代理(基本{
获取(目标、关键){
info(`Get on属性“${key}`)
if(禁止方法索引)(键)!=-1){
抛出新错误(“禁止”);
}
返回扩展[键]?扩展[键]:目标[键];
}
});
对于(变量i=0;i }
“[].concat(arrayobj)或arrayobj.concat([])返回长度相同的新数组对象,此新数组的每个索引都包含一个新的/重复的对象”这是不正确的。它与使用.slice
的结果相同。您正在寻找一个简单的for
循环,该循环迭代数组的每个元素,克隆它并将其分配回相同的位置。但是克隆对象并没有内置到JavaScript中。请看,我认为这里真正的问题是“如何创建对象的副本?”@FelixKling“slice()方法将数组的一部分的浅拷贝返回到一个新的数组对象中……用于对象引用(而不是实际对象),slice将对象引用复制到新数组中。原始数组和新数组都引用同一个对象。如果引用的对象发生更改,则新数组和原始数组都可以看到这些更改。“@BenjaminMcFerren:是的,我没有对此提出疑问。我说的是[].concat(数组)
的作用完全相同(与.slice(0)
当然可以)。@BenjaminMcFerren你能给出一个用例吗?我很难想出一个很好的例子来说明如何使用它。如果你引用的是原始数组,数组中的每个元素都是一个内存块。如果你说arr[1],那永远是arr[1]除非您将arr重新分配到一个新变量中,该变量只能a.指向arr的内存位置,或B.创建一个副本,不再引用原始数组。基本上,我认为您不能同时拥有这两个变量。
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]