为何使用扩展运算符拷贝数组仍未通过原数组不变性测试?
问题原因分析
你遇到的核心问题是浅拷贝的局限性:扩展运算符[...arr]、slice()、Array.from()确实能创建原数组的浅拷贝,但数组里的对象元素是引用类型,浅拷贝只会复制对象的引用,而不是对象本身。这意味着alteredArr里的每个person和原数组input里的person指向的是同一个内存地址的对象,所以你修改person.location时,本质上是在修改原数组里的那个对象,测试自然会失败。
解决方案
要让原数组完全不被修改,你需要在处理数组元素时,为每个对象创建新的拷贝,而不是直接修改原对象。可以通过map方法结合对象扩展运算符来实现:
function updateRemoteStudents(arr) { return arr.map(person => { // 如果对象已有location属性,返回原对象的拷贝;否则添加location后返回新对象 if (person.hasOwnProperty('location')) { return { ...person }; } return { ...person, location: 'remote' }; }); }
或者更简洁的写法:
function updateRemoteStudents(arr) { return arr.map(person => ({ ...person, // 仅当不存在location时才添加该属性 ...(!person.hasOwnProperty('location') && { location: 'remote' }) })); }
为什么这样有效?
map方法会返回一个全新的数组,不会修改原数组。{ ...person }创建了原对象的浅拷贝,新对象和原对象是独立的引用,修改新对象的属性不会影响原对象。- 对于没有
location的对象,我们在拷贝的基础上添加location: 'remote',最终返回的是一个新对象,原对象完全保持不变。
现在再运行你的测试,原数组input的内容就不会被修改,测试就能通过了。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

