3

我对 JavaScript 和 d3 比较陌生,但我对强制导向的布局非常感兴趣。在 Mike Bostock 的力导向可视化中,他倾向于使用以下代码(或类似代码)从链接列表中解析节点:

var links = [
    {source: "A", target: "B"},
    {source: "B", target: "C"},
    {source: "C", target: "A"}];

var nodes = {};

links.forEach(function(link) {
    link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
    link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
});

我完全理解他在这里最终完成了什么,我只是想forEach更好地理解循环中的 JavaScript 语法(实际上,完全没有)。如果有人可以解释,我将非常感激。

这显然是非常优雅的代码,但我在互联网上的任何地方都找不到解释——我可能在搜索中遗漏了一个关键术语,所以我很不情愿地在这里问这个问题。真正让我失望的是:

  • 两边的两个任务是||做什么的,
  • 每行的第一次分配的顺序(每行的左侧||):例如,为什么link.source = nodes[link.source]不是nodes[link.source] = link.source
4

1 回答 1

2

在下面的代码中

link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});

它的意思是

link.source = nodes[link.source]

如果nodes[link.source]不是未定义的。

如果未定义nodes[link.source],则下面的块将被执行。

(nodes[link.source] = {name: link.source})//assigning new value to nodes[link.source]

并且上面的值将被设置为link.source

所以,如果你把它简单化,它会像:

link.source = nodes[link.source] || (nodes[link.source] = {name: link.source}); 相当于:

if (!nodes[link.source]) {//not undefined
 link.source = nodes[link.source];
} else {
 nodes[link.source] = {name: link.source}
 link.source = nodes[link.source];
}

希望这可以帮助!

对您的评论的解释

问题 (a = b || c equates to a = b but if b is undefined make a = c, right?)

是的

问题仍然没有意义的是为什么这些分配的左侧是link.source和link.target?那些已经定义,它们是我们想要填充节点的东西?

是的!你在这里是对的Those are already defined。link.source 当前为 = "A" 块执行后,每个 link.source 将指向一个对象,如下所示。link.source = {name:A}

如果您仍然有困惑,请告诉我。

于 2017-08-31T08:18:34.363 回答