【问题标题】:variable declaration conditional syntax变量声明条件语法
【发布时间】:2014-07-24 09:44:58
【问题描述】:

当我看到类似的东西时,我正在寻找一些很棒的 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. 由于 nodes[link.source] 是一个对象,link.source 需要它的引用。这总是在发生。

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

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

    如果没有定义并返回 false,OR 子句强制执行...

  3. nodes[link.source] 获得了一个值,因此感谢引用 link.source 指向相同的值。

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

我在某个地方错了吗?第 2 点对我来说似乎很奇怪。

【问题讨论】:

    标签: javascript variables syntax d3.js


    【解决方案1】:

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

    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。

    编辑:您编辑的解释是正确的。基本上就是这样。

    【讨论】:

      【解决方案2】:

      我的理解

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

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

      那么就做link.source = nodes[link.source] = {name: link.source};

      【讨论】:

        【解决方案3】:
        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" },
        }
        

        【讨论】:

        • 在这种情况下,外部检查 if(link.source != nodes[link.source]) { 实际上不是必需的(原始代码中也不存在)。
        • 它是隐式的(link.source 最终应该等于nodes[link.source])并且可以防止重复值设置link.source = nodes[link.source]; 超过一次。
        • 这是一张地图——不确定如何在其中获得重复值?不,这不是隐含的。如果存在重复值,原始代码将进行多次赋值。
        • 我说的是links,其中source 等于test1 多次,如果我删除外部检查,这将导致link.source = nodes[link.source]; 被多次调用。原来是一个快捷代码,所以很明显,扩展它可以有多种不同的方式,如果需要优化,可能会导致不同的代码(结果当然必须保持完全相同)。
        • 啊,但是link 在循环中,所以每次都会指向不同的对象。这段代码不会被多次执行,link 是同一个对象。
        猜你喜欢
        • 1970-01-01
        • 2015-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-09
        • 2014-09-22
        • 1970-01-01
        相关资源
        最近更新 更多