为何JS数组全等判断可精准删除目标项目?空数组场景疑问
为什么仅删除指定的空数组项目?
代码示例
const removeProject = (children) => { UI.myProjects.forEach(project => { if (project.myTasks === children) { UI.myProjects.splice(UI.myProjects.indexOf(project), 1) } }); }
问题背景
我通过项目工厂创建项目,每个项目都带有专属的myTasks数组,初始状态下所有数组都是空的。UI.myProjects是存储所有项目的数组。触发上述函数时,会遍历所有项目,对比项目的myTasks数组和传入的children(待删除项目的myTasks数组),匹配上就删除对应项目。
但出现了一个疑问:当创建多个带有空myTasks数组的项目,且传入的children也是空数组时,函数只删除我指定的项目,不会影响其他同样带空myTasks数组的项目。比如:
UI.myProjects = [ { myTasks: [] }, // 随机项目1 { myTasks: [] }, // 随机项目2 { myTasks: ['bla bla']}, // 随机项目3 { myTasks: []} // 待删除项目 ]
触发函数后仅删除“待删除项目”,前两个项目不受影响。我猜测和数组的父对象有关,但我只传入了数组而非整个项目,想了解具体原理。
原理解释
核心原因是JavaScript中引用类型的相等判断规则:
- 数组属于引用类型,这类值在内存中存储的是引用地址,而非实际内容。
- 当你用
===比较两个引用类型时,比较的是它们的内存引用地址是否相同,而不是内容是否一致。
你的项目工厂每次创建项目时,都会生成一个新的空数组作为myTasks——也就是说,每个项目的myTasks都是内存中独立的引用,哪怕它们的内容都是空的。比如随机项目1的myTasks、随机项目2的myTasks、待删除项目的myTasks,是三个完全不同的内存引用。
当你传入待删除项目的myTasks作为children参数时,project.myTasks === children只有当某个项目的myTasks和children是同一个内存引用时才会返回true——也就是你指定的那个待删除项目。其他项目的空数组虽然内容相同,但引用地址不同,所以不会被匹配到,自然不会被删除。
内容的提问来源于stack exchange,提问作者Kamran Huseynov
相关产品推荐
相关产品推荐

