我具有创建对象的构造函数
我初始化了一个名为arr1
的数组,调用该函数以获取初始值。
我在arr1
上绘制arr2
但是我原来的arr1
被更改了。为什么是这样?是因为初始化数组和事件循环时正在进行异步回调吗?
作为参考,我试图从上一篇有关画布here的帖子中提取构想,以供重构
function point(x,y){
return {x,y}
}
arr1 = [point(1,2), point(3,4)];
console.log(arr1, "arr1");
arr2 = arr1.map(b=>{
b.x = b.x+2;
b.y = b.y+2;
return b;
})
console.log(arr1, "arr1");
console.log(arr2, "arr2");
答案 0 :(得分:3)
在您的map
回调中,您正在直接更改每个对象的属性(b
)...
b.x = b.x+2;
b.y = b.y+2;
我怀疑你追求的是更不变的东西
const arr2 = arr1.map(({x, y}) => ({
x: x + 2,
y: y + 2
}))
这将创建一个具有+2值的新数组,而完全不修改原始数组。
function point(x,y){
return {x,y}
}
const arr1 = [point(1,2), point(3,4)];
console.log('arr1', arr1);
const arr2 = arr1.map(({x, y}) => ({
x: x + 2,
y: y + 2
}))
console.info('arr1', arr1);
console.info('arr2', arr2);
答案 1 :(得分:2)
其他人指出了在地图中重新分配arr
的值的问题,但是我想指出您在arr1
上第一次控制台登录时观察到的副作用正在更新。这是控制台在大多数浏览器中的工作方式的局限性(有人会说并非如此)。如果您在打开嵌套对象(或数组)之前更改了嵌套对象(或数组),并观察到控制台日志中的第一个对象,它将被更新为新值。
function point(x,y){
return {x,y}
}
arr1 = [point(1,2), point(3,4)];
console.log("arr1 closed", arr1);
console.log("arr1 opened:", arr1[0], arr1[1]);
arr1[0] = {x: 15, y:42};
console.log("arr1 closed", arr1);
console.log("arr1 opened:", arr1[0], arr1[1]);
请注意“打开的”数组如何在调用控制台日志时显示状态值,但是如果您使用嵌套数组扩展第一个控制台日志,它将显示更新后的值。
您不能将此代码作为片段运行并观察到这种副作用。它必须在浏览器中运行,以便可以打印到控制台。
答案 2 :(得分:2)
使用map时,将创建一个新数组,但该数组保留对对象的引用。因此,当您更改地图中的对象b
时,这是对原始点的引用,而不是副本。
function point(x,y){
return {x,y}
}
arr1 = [point(1,2), point(3,4)];
arr2 = arr1.map((b, i)=>{
// b IS on of the objects from arr1
console.log(`b === arr1[${i}]`, b === arr1[i])
b.x = b.x+2;
b.y = b.y+2;
return b;
})
您可以改成新的point
:
function point(x,y){
return {x,y}
}
arr1 = [point(1,2), point(3,4)];
arr2 = arr1.map(({x, y}) => point(x + 2, y + 2))
console.log(arr1, "arr1")
console.log(arr2, "arr2")
答案 3 :(得分:2)
您看到此行为的原因是.map()
浅复制元素到新数组。
此行使源数组中每个元素的x
和y
值发生变化。
arr2 = arr1.map(b=>{
b.x = b.x+2;
b.y = b.y+2;
return b;
})
相反,您应该只返回新的x
和y
值,而不用像这样修改源数组元素
arr2 = arr1.map(b => {
return {
x: b.x + 2,
y: b.y + 2
};
})
您可以尝试使用下面的代码片段创建一个具有更新的x
和y
值的新数组,而无需更改源数组元素。
function point(x, y) {
return { x, y }
}
arr1 = [point(1, 2), point(3, 4)];
console.log(arr1, "arr1");
arr2 = arr1.map(b => {
return {
x: b.x + 2,
y: b.y + 2
};
})
console.log(arr1, "arr1");
console.log(arr2, "arr2");