首页 > 解决方案 > 用于深度优先搜索的 Javascript 扩展运算符

问题描述

我正在尝试使用扩展运算符...将项目附加到深度优先搜索的数组中。但是,它显示出奇怪的行为:

例如:如果search()为这样的树递归调用函数:

   A
  /\
 B C
/
D

使用扩展运算符,log看起来像这样:

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()log

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;
    }
}

标签: javascriptecmascript-6

解决方案


问题不在于您使用扩展运算array.push()还是与所有父搜索数组断开连接。array = [...array, this.name]

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

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


推荐阅读