JavaScript中修改find方法返回值会改变原数组的原因是什么
let arr = [{ age: 3 }, { age: 5 }, { age: 6 }, { age: 7 }]; let exists = arr.find(x => x.age < 4); exists.age += 1; console.log(arr); //output is [{age:4},{age:5},{age:6},{age:7}];
现象原因解释
- JavaScript中的数据分为两类,遵循不同的赋值逻辑:
- 值类型(原始类型):包含Number、String、Boolean、Null、Undefined、Symbol、BigInt,赋值时会直接复制值本身,修改新变量不会影响原始值
- 引用类型:包含Object、Array、Function等,变量存储的是值在堆内存中的引用地址,赋值时仅复制引用地址,新旧变量指向内存中同一个值
Array.find()方法匹配到元素后,如果元素是引用类型,返回的是该元素的内存引用地址,而非独立的拷贝副本
示例中的数组元素都是引用类型的普通对象,exists变量和原数组中第一个元素指向堆内存中的同一个对象,修改exists.age本质就是修改这个公共内存地址中存储的属性值,因此原数组的对应元素会同步变化。
避免修改原数组的处理方案
如果需要修改匹配结果且不影响原数组,可以对find返回的结果做拷贝处理:
let arr = [{ age: 3 }, { age: 5 }, { age: 6 }, { age: 7 }]; // 对匹配结果做浅拷贝,生成独立的新对象 let exists = {...arr.find(x => x.age < 4)}; exists.age += 1; console.log(arr); // 输出为 [{age:3},{age:5},{age:6},{age:7}],原数组不受影响
若对象内部嵌套了其他引用类型,浅拷贝无法完全隔离影响,需要使用深拷贝方案处理。
内容的提问来源于stack exchange,提问作者Abbas Shaikh
相关产品推荐
相关产品推荐

