问题
I'm relatively new to JavaScript and d3, but I'm really interested in force-directed layouts. In Mike Bostock's force-directed visualizations, he tends to parse nodes from a list of links using the following code (or similar):
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});
});
I completely understand what he ultimately accomplishing here, I just want to understand the JavaScript syntax in the forEach
loop better (actually, at all). If someone could explain, I'd really appreciate it.
It's obviously very elegant code, but I can't find an explanation anywhere on the internet - I'm probably missing a key term in my searches, so I'm reluctantly asking the question here. What is really throwing me off:
- What the two assignments on either side of the
||
do , - The order of the first assignment of each line (left-hand side of each
||
): why is itlink.source = nodes[link.source]
notnodes[link.source] = link.source
, for instance.
回答1:
In the code below
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
It means
link.source = nodes[link.source]
if nodes[link.source]
is not undefined.
If nodes[link.source]
is undefined then block below will get executed.
(nodes[link.source] = {name: link.source})//assigning new value to nodes[link.source]
and the above value will be set to link.source
So if you make it simple it would be like:
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
is equivalent to:
if (!nodes[link.source]) {//not undefined
link.source = nodes[link.source];
} else {
nodes[link.source] = {name: link.source}
link.source = nodes[link.source];
}
Hope this helps!
Explanation for your comment
Question (a = b || c equates to a = b but if b is undefined make a = c, right?)
YES
Question What still doesn't make sense is why the left side of these assignments are link.source and link.target?Those are already defined, they're what we want to populate nodes with?
Yes! you are correct here Those are already defined
.
link.source is currently = "A"
After the block executes each link.source will be pointing to an object, something like this. link.source = {name:A}
Let me know if you still have confusion.
来源:https://stackoverflow.com/questions/45974522/explain-mike-bostock-node-parsing-loop