我正在尝试使用扩展运算符 ...
将项目附加到深度优先搜索中的数组中。然而,它表现出奇怪的行为:
- 使用
array.push()
,数组是正确的:['a','b','c','d]; - 使用
[...array, this.name]
,数组每次都不同。
例如:如果为这样的树递归调用 search()
函数:
A
/\
B C
/
D
使用展开运算符,日志
如下所示:
array = []
this.name = A
array = [A];
=====
array = [A]
this.name = B
array = [A,B]
=====
array = [A,B]
this.name = D
array = [A,B,D]
====
array = [A] // not [A,B,D]
this.name = C
array = [A,C]
使用push()
,日志
如下所示:
array = []
this.name = A
array = [A];
=====
array = [A]
this.name = B
array = [A,B]
=====
array = [A,B]
this.name = D
array = [A,B,D]
====
array = [A,B,D]
this.name = C
array = [A,B,D,C] // expected
class Node {
constructor(name) {
this.name = name;
this.children = [];
}
addChild(name) {
this.children.push(new Node(name));
return this;
}
search(array) {
console.log('this name:');
console.log(this.name);
console.log('array before:');
console.log(array);
// array.push(this.name);
array = [...array, this.name];
console.log('array after');
console.log(array);
for (let child of this.children) {
child.search(array);
}
return array;
}
}
最佳答案
问题不在于您是否使用扩展运算符或 array.push()
,只是您的实现依赖于将搜索数组的同一实例传递给所有节点,但每次运行 array = [...array, this.name]
时您正在创建一个新数组实例,该实例现已与所有父搜索数组断开连接。
详细说明一下,array.push()
变异 array
- 它仍然是相同的数组实例,只是具有新内容。但是array = [...]
,无论数组文字中有什么,都会创建一个包含新内容的新数组 - 对旧数组的引用,即传递给 search()
的数组。节点的父节点的函数将被丢弃。对 array
的所有进一步修改节点的父节点不会知道。
因为您需要在每个搜索函数中修改相同的数组实例,所以您只需使用 array.push()
并且不传播,或传递包含 array
的对象到每个函数,以便每个分支的节点都可以访问相同的数组实例,无论它是否被重新分配。
关于用于深度优先搜索的 Javascript 扩展运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59146102/