如何从数组arr2中移除元素并保持其引用关系?
如何从数组arr2中移除元素并保持其引用关系?
看起来你已经精准抓住了数组作为引用类型的核心特性——当你把arr2赋值给arr3时,它们指向的是内存里同一个数组实例,所以修改其中一个,另一个必然同步变化。你想要的就是在移除元素的同时,维持这种引用关联对吧?
先看你给出的这个场景,能直观看到引用关系的表现:
let arr2=['aa','bb','cc','dd']; let arr3=arr2; arr2.remove('bb'); console.log(arr2);//['aa','cc','dd']; console.log(arr3);//['aa','cc','dd']; arr3.remove('aa');//['cc','dd']; console.log(arr2);//['cc','dd']; console.log(arr3);//['cc','dd'];
你一开始的思路方向完全正确:先找到目标元素的索引,再把它和数组最后一个元素交换位置,最后移除最后一个元素。这种方法不仅能保持原数组的引用关系(因为我们直接修改的是原数组本身),还比splice更高效——毕竟splice会导致后续元素移位,而交换+pop的操作复杂度是O(1)。
不过这里要修正一下findIndex的写法,它需要传入一个回调函数,完整的实现可以这样:
方法1:给数组原型添加自定义remove方法
// 给数组原型添加自定义remove方法,模拟你示例里的功能 Array.prototype.remove = function(item) { // 找到目标元素的索引 const index = this.findIndex(el => el === item); if (index !== -1) { // 交换目标元素和最后一个元素的位置 this[index] = this.at(-1); // 移除最后一个元素(也就是原来的目标元素) this.pop(); } }; // 测试验证 let arr2=['aa','bb','cc','dd']; let arr3=arr2; arr2.remove('bb'); console.log(arr2); // ['aa','cc','dd'] console.log(arr3); // ['aa','cc','dd'] arr3.remove('aa'); console.log(arr2); // ['cc','dd'] console.log(arr3); // ['cc','dd']
方法2:使用独立工具函数(不修改原型)
如果你不想污染数组原型,也可以写一个独立的工具函数:
function removeFromArray(arr, item) { const index = arr.findIndex(el => el === item); if (index !== -1) { arr[index] = arr.at(-1); arr.pop(); } } // 使用方式 let arr2=['aa','bb','cc','dd']; let arr3=arr2; removeFromArray(arr2, 'bb'); console.log(arr2); // ['aa','cc','dd'] console.log(arr3); // ['aa','cc','dd']
不管用哪种方式,核心都是直接修改原数组实例,所以arr2和arr3的引用关系会一直保持,修改其中一个,另一个也会同步更新。
备注:内容来源于stack exchange,提问作者yutingbai
相关产品推荐
相关产品推荐

