变量声明条件语法

时间:2014-07-24 09:44:59

标签: javascript variables syntax d3.js

当我看到类似的东西时,我正在寻找一些很棒的d3.js code examples

var links = [
  {source: "test1", target: "test2"},
  {source: "test1", target: "test3"},
  {source: "test2", target: "test3"},
  {source: "test3", target: "test4"}
];

var nodes = {};

// Compute the distinct nodes from the links.
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});
});

我没有立即得到如何声明var节点。

我的第一个猜测是将其翻译成:

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

但链接不再被绘制了。

这两种方法有什么区别?

初始语法的重点是,只是一个快捷方式还是增加了性能?

在这种情况下是否有最好的做法?

修改

所以如果我试着完全理解

link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
  1. 由于节点[link.source] 是一个对象 link.source 获取其引用。这种情况总是在发生。

  2. OR条件,我不确定会得到那个部分。

    我想如果 nodes [link.source] 被定义 link.source = nodes [link.source] 返回true,我们不需要更进一步。

    如果没有定义并返回false,则OR子句强制进一步......

  3. 节点[link.source] 获取一个值,因为引用 link.source 指向相同的值。

    我想在这个阶段 link.source 还没有包含对 nodes [link.source] 的引用,但它的初始值。它将包含逗号后的新引用。

  4. 我错了吗?第2点对我来说很奇怪。

3 个答案:

答案 0 :(得分:2)

示例中使用的代码只是一个语法快捷方式。它相当于

links.forEach(function(link) {
  if(nodes[link.source]) { // we already know about the source of this link
    link.source = nodes[link.source];
  } else { // we haven't seen this source before, create a new node for it
    nodes[link.source] = {name: link.source};
    link.source = nodes[link.source];
  }

  if(nodes[link.target]) { // we already know about the target of this link
    link.target = nodes[link.target];
  } else { // we haven't seen this target before, create a new node for it
    nodes[link.target] = {name: link.target};
    link.target = nodes[link.target];
  }
});

所有这一切都是必要的,因为节点只是通过链接隐式声明 - 也就是说,没有节点列表,只能通过遍历链接来组装节点,并且"收获"来源和目标。这就是nodes中存储的内容 - 它是从节点ID(从链接)到表示节点的对象的映射。

上面的代码通过为看不见的节点(即映射中不存在的节点)创建新对象并插入相应的映射来同时填充此映射。然后更新链接的源和目标以指向那些对象(稍后将通过力布局操作以设置其位置),而不是原始数据中引用的节点的ID。

编辑:您编辑的解释是正确的。这基本上就是发生的事情。

答案 1 :(得分:0)

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

可以翻译成:

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

(与link.target相同)

所以:

var links = [
  {source: "test1", target: "test2"},
  {source: "test1", target: "test3"},
  {source: "test2", target: "test3"},
  {source: "test3", target: "test4"}
];

将转换为:

links = [
  {source: { name: "test1" }, target: { name: "test2" }},
  {source: { name: "test1" }, target: { name: "test3" }},
  {source: { name: "test2" }, target: { name: "test3" }},
  {source: { name: "test3" }, target: { name: "test4" }}
];

和节点将等于:

nodes = {
    "test1": { name: "test1" },
    "test2": { name: "test2" },
    "test3": { name: "test3" },
    "test4": { name: "test4" },
}

答案 2 :(得分:0)

我对

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

是,如果nodes[link.source]不存在

然后只做link.source = nodes[link.source] = {name: link.source};