如何通过Object.assign与map避免原数据中position属性被篡改?
解决数组map时避免篡改原对象position属性的问题
哦,我懂你遇到的这个困扰!你已经尝试用Object.assign来创建新对象,但还是不小心修改了原数组的position,核心问题出在你直接修改了原对象的position属性值,而不是创建一个新的position对象。
让我拆解一下你的代码问题:
position: { x: (e.position.x -= bbX / 2 - parent.x), y: (e.position.y -= bbY / 2 - parent.y) }
这里的e.position.x -= ...是直接对原数组元素e的position.x进行赋值操作,哪怕你用Object.assign({}, e)复制了外层对象,position依然是引用原对象的内存地址,所以原数组的position自然会被篡改。
正确的解决方法
我们需要基于原position的值计算新坐标,完全不修改原position对象,而是创建一个全新的position对象来替换:
方法1:用展开运算符(更简洁)
const newData = data.map(e => { if (!e.parent) { // 即使没有parent,也返回原对象的浅拷贝,保持一致性 return { ...e, position: { ...e.position } }; } // 基于原position的值计算新坐标,不修改原对象 const newX = e.position.x - (bbX / 2 - parent.x); const newY = e.position.y - (bbY / 2 - parent.y); // 创建新对象,包含原属性+新的position return { ...e, position: { x: newX, y: newY } }; });
方法2:用Object.assign(和你原来的思路对齐)
const newData = data.map(e => { if (e.parent) { // 先计算新的坐标值,不碰原position const newX = e.position.x - (bbX / 2 - parent.x); const newY = e.position.y - (bbY / 2 - parent.y); // 创建新的position对象 const newPosition = Object.assign({}, e.position, { x: newX, y: newY }); // 创建新的外层对象 const newObject = Object.assign({}, e, { position: newPosition }); return newObject; } // 返回原对象的浅拷贝,避免直接返回原引用 return Object.assign({}, e, { position: Object.assign({}, e.position) }); });
为什么这样有效?
我们不再直接修改e.position.x或e.position.y,而是读取它们的原始值来计算新坐标,然后把新坐标放到全新的position对象里,再将这个新对象赋值给新创建的外层对象。这样原数组里的position对象完全不会被修改,彻底避免了数据突变。
如果你的position未来有更深层次的嵌套(比如position: { x: 10, y:10, offset: { left: 5 } }),那需要用到深拷贝,但目前你的场景下,浅拷贝(复制x和y)就足够了。
内容的提问来源于stack exchange,提问作者anime




