由于最近在做的项目中设计到了虚拟dom的设计,那自然就避免不了需要对虚拟dom中的节点进行遍历/查找了,一般来说查找节点无非就两种方法 - 广度优先查找和深度优先查找,这跟我们在数据结构中学习到的树的遍历其实是一样的。ok,废话不多说,讲一下我对这两种查找方法的理解吧。
首先广度优先查找,BFS,它的一个特点就是应用到了队列的先进先出的特性,通过这个队列来存储第一次发现的节点,以便下一次的处理。
1 /**
2 *
3 * @param {*} target: 目标节点,要在哪个节点里面进行搜索
4 * @param {*} prop: 搜索索引
5 * 索引条件在isLegal()里面进行修改
6 */
7 function breadthSearch(target){
8 const nodeList = [target];
9 let index = 0;
10 while (index < nodeList.length) {
11 const node = nodeList[index++];
12 if (node.children && node.children.length > 0) {
13 for (let k in node.children) {
14 nodeList.push(node.children[k]);
15 }
16 }
17 }
18 return function(prop) {
19 let targetNodeList = [];
20 for (let node of nodeList) {
21 if(isLegal(node, prop)) {
22 targetNodeList.push(node);
23 }
24 }
25 return targetNodeList;
26 }
27 }
其次是深度优先查找,DFS,顾名思义这是一种“一探到底”的查找算法,它会一直搜索到某一个节点的最深处,再通过回溯的方法寻找到另外一个节点的最深处,以此循环。
1 /**
2 *
3 * @param {*} target: 目标节点,要在哪个节点里面进行搜索
4 * @param {*} prop: 搜索索引
5 * 索引条件在isLegal()里面进行修改
6 */
7 function depthSearch(target){
8 const nodeList = [];
9 const depthEach = function(item) {
10 nodeList.push(item);
11 if(item.children){
12 for(let k in item.children){
13 depthEach(item.children[k]);
14 }
15 }
16 }
17 depthEach(target);
18 return function(prop) {
19 let targetNodeList = [];
20 for (let node of nodeList) {
21 if(isLegal(node, prop)) {
22 targetNodeList.push(node);
23 }
24 }
25 return targetNodeList;
26 }
27 }