优雅的convert list to tree by JS reference

234 阅读1分钟

菜鸟的懵懂

抛砖引玉

相信作为前端小白阶段经常被问及,函数传参是值传递还是引用传递?

let num = 0;
const obj = { a: 0 };

function test(num, obj) {
  num = 1;
  obj.a = 1;
  console.log(num, obj); // 1, {a:1}
}

test(num, obj);
console.log(num, obj); // 0, {a:1}

这里执行test方法之后,为什么num值还是0,而obj变成了{a:1}。原因就是JavaScript的数据类型导致的,引用类型数据赋值的时候是赋值数据内存地址, 而test改变了obj数据的内容,但是它的值地址还是传参的地址,所以obj变量的内容也同步被改变了。

JavaScript 数据类型

image.png

回归正题

如何将一个list结构的数据转换成tree结构?

话不多说,直接show you my code

const list = [
  { id: '01', parentId: '0', name: '节点1' },
  { id: '011', parentId: '01', name: '节点1-1' },
  { id: '0111', parentId: '011', name: '节点1-1-1' },
  { id: '02', parentId: '0', name: '节点2' },
  { id: '022', parentId: '02', name: '节点2-2' },
  { id: '023', parentId: '02', name: '节点2-3' },
  { id: '0222', parentId: '022', name: '节点2-2-2' },
  { id: '03', parentId: '0', name: '节点3' },
];

const makeTree = (list) => {
  const tree = { id: '0', children: [] };
  const arr = [tree, ...list];

  arr.forEach((node) => {
    const parent = arr.find((item) => node.parentId === item.id);
    if (!parent) return;
    if (parent.children === undefined) {
      parent.children = [];
    }
    parent.children.push(node);
  });

  return tree;
};

const tree = makeTree(list);

console.log(tree);

解释一下:这里的node和parent是引用类型数据,所以对数据children字段的更新是直接反馈给了list的node,成功的实现了convert list to tree

优化

makeTree之后,list的node内容其实也对应被改变,这里就引入新的问题:深拷贝

未完待续...