admin管理员组文章数量:1389863
I have constructor function that creates an object
I initialize an array called arr1
, calling the function to make starting values.
I map over the arr1
to make arr2
But my original arr1
was changed. Why is this? Is it because I'm making async callbacks when initializing array and event-loops?
For reference, I was trying to take ideas from my previous post about canvas here for refactoring
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");
I have constructor function that creates an object
I initialize an array called arr1
, calling the function to make starting values.
I map over the arr1
to make arr2
But my original arr1
was changed. Why is this? Is it because I'm making async callbacks when initializing array and event-loops?
For reference, I was trying to take ideas from my previous post about canvas here for refactoring
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");
Share
Improve this question
edited Nov 28, 2018 at 6:46
Nathan
6365 silver badges19 bronze badges
asked Nov 28, 2018 at 5:29
Vincent TangVincent Tang
4,1486 gold badges52 silver badges71 bronze badges
4 Answers
Reset to default 3In your map
callback, you are directly altering properties of each object (b
)...
b.x = b.x+2;
b.y = b.y+2;
What I suspect you're after is something more immutable like
const arr2 = arr1.map(({x, y}) => ({
x: x + 2,
y: y + 2
}))
This will create a new array with +2 values without modifying the original at all.
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);
When you use map, you create a new array, but the array holds references to the objects. So when you alter the object b
in the map, this is a reference to the the original points, not copies.
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;
})
You could make a new point
instead:
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")
The reason for the behaviour you are seeing is .map()
shallow copies the elements to a new array.
This line mutates x
and y
values in each element in the source array.
arr2 = arr1.map(b=>{
b.x = b.x+2;
b.y = b.y+2;
return b;
})
Instead you should only return new x
and y
values without mutating source array element like this
arr2 = arr1.map(b => {
return {
x: b.x + 2,
y: b.y + 2
};
})
You could try the snippet below to create a new array with updated x
and y
values without mutating the source array elements.
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");
Others have pointed out the issue with re-assigning the values of your arr
in your map, but I wanted to point out the side effect that you observed with your first console log on arr1
also being updated. This is a limitation (some would argue it isn't) of with how the console works in most browsers. If you change a nested object (or array) before you open and observe the first object in the console log, it will be updated to the new values.
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]);
jsFiddle
Notice how the "opened" arrays show the values at the state of when the console log was called, but if you expand the first console log with the nested array, it shows the updated values.
You can't run this code as a snippet and observe this side effect. It must be run in the browser so it can print to the console.
本文标签: Javascript Array Map unexpectedly changed original array valuesStack Overflow
版权声明:本文标题:Javascript Array Map unexpectedly changed original array values - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744683492a2619558.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论