用于深度优先搜索的Javascript扩展运算符

用于深度优先搜索的Javascript扩展运算符,javascript,ecmascript-6,Javascript,Ecmascript 6,我正在尝试使用扩展运算符…在深度优先搜索中将项附加到数组中。然而,它表现出奇怪的行为: 使用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.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]
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
使用spread运算符,
log
如下所示:

   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]
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
使用
push()

   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]
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
类节点{
建造师(姓名){
this.name=名称;
这是:children=[];
}
addChild(姓名){
this.children.push(新节点(名称));
归还这个;
}
搜索(数组){
log('此名称:');
console.log(this.name);
log('array before:');
console.log(数组);
//array.push(this.name);
array=[…array,this.name];
log('array after');
console.log(数组);
为了(让这个孩子,孩子们){
子搜索(数组);
}
返回数组;
}
}

问题不在于是否使用扩展运算符或
数组.push()
,而在于您的实现依赖于将搜索数组的相同实例传递给所有节点,但每次运行
数组=[…array,this.name]
您正在创建一个新数组实例,该实例现在已与所有父搜索数组断开连接

更详细地说,
array.push()
变异了
array
——它仍然是相同的数组实例,只是有了新的内容。但是
array=[…]
无论数组文本中包含什么,都会创建一个包含新内容的新数组-对旧数组的引用,即节点父节点传递给
search()
函数的引用,将被丢弃。节点的父节点将不知道对
数组
的所有进一步修改


因为您需要在每个搜索函数中修改相同的数组实例,所以您只需使用
array.push()
而不扩散,或者将包含
数组的对象传递给每个函数,以便每个分支的节点都可以访问相同的数组实例,而不管它是否已被重新分配。

问题不在于是否使用扩展运算符或
数组.push()
,很简单,您的实现依赖于将搜索数组的同一实例传递给所有节点,但每次运行
array=[…array,this.name]
时,您都在创建一个新数组实例,该实例现在与所有父搜索数组断开连接

更详细地说,
array.push()
变异了
array
——它仍然是相同的数组实例,只是有了新的内容。但是
array=[…]
无论数组文本中包含什么,都会创建一个包含新内容的新数组-对旧数组的引用,即节点父节点传递给
search()
函数的引用,将被丢弃。节点的父节点将不知道对
数组
的所有进一步修改



因为您需要在每个搜索函数中修改相同的数组实例,所以您只需使用
array.push()
且不扩散,或者将包含
array
的对象传递给每个函数,以便每个分支的节点都可以访问相同的数组实例,而不管它是否已被重新分配。

您没有问任何问题。至少你需要解释“数组每次都不同”的意思。确切地说,我每次都得到相同的数组。你能提供复制的工作示例吗?对不起,我第一次不清楚。我添加了更多细节。在这种情况下,Spread语法更为正确(您的
push
实现只是偶然工作):在递归算法中共享数据会导致灾难。所以
array=[A,C]
-这是完全可以预料的,您可以独立地迭代每个节点。如果要合并结果,必须手动合并,就像其他递归算法一样<代码>子搜索(数组)@zerkms。我试过这个
让c=[…数组,this.name];for(让child of this.children){child.search(c);}返回c但它不起作用。你没有问任何问题。至少你需要解释“数组每次都不同”的意思。确切地说,我每次都得到相同的数组。你能提供复制的工作示例吗?对不起,我第一次不清楚。我添加了更多细节。在这种情况下,Spread语法更为正确(您的
push
实现只是偶然工作):在递归算法中共享数据会导致灾难。所以
array=[A,C]
-这是完全可以预料的,您可以独立地迭代每个节点。如果要合并结果,必须手动合并,就像其他递归算法一样<代码>子搜索(数组)@zerkms。我试过这个
让c=[…数组,this.name];for(让child of this.children){child.search(c);}返回c但它不起作用。谢谢@Klaycon。你的回答有道理。你能再详细解释一下吗?比如为什么
push()
会维护更新的数组而
扩展操作符
不会维护更新的数组?@Vieta因为
.push
根据定义会变异相同的数组。一个新的数组操作
[…]
会创建一个新数组。我明白了。这是有道理的。谢谢。@Vieti我已经编辑了答案,并提供了更多细节,但虫族似乎已经涵盖了它。很高兴为你清理干净。谢谢你@Klaycon。你的回答有道理。你能再详细解释一下吗?比如为什么
push()
会维护更新的数组而
扩展操作符
不会维护更新的数组?@Vieta因为
.push
根据定义会变异相同的数组。一个新的数组操作
[…]
将创建一个新的