【发布时间】:2023-03-08 19:39:01
【问题描述】:
作为 d3 和 javascript 的新手,我正在尝试通过查看提供的版本来了解可折叠树的工作原理
http://bl.ocks.org/mbostock/4339083
具体来说,我不明白以下语句如何以及为什么在更新节点后成功地为节点分配唯一 ID。
// 更新节点…
var node = svg.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
我的理解是nodes是一个数组,这个数组有一个关联的索引i。 每次更新节点时,上述语句使用从数组索引 i 派生的 id 的唯一键值将新节点(如数据)与网页上的节点(如视觉表示)绑定。如果nodes数组的一个元素没有id,就会被赋值为++i。
这就是我感到困惑的地方。假设第一个节点数组有 4 个元素,因此每个元素的 id 为 1、2、3 和 4。我折叠树,现在新节点数组有 3 个元素,它们恰好与第一个节点的前三个元素相同大批。这些元素的 id 为 1,2 和 3。到目前为止没有问题。
现在下一个更新的节点数组有 4 个元素,前 3 个元素相同,第 4 个元素不同。 上面的代码正确地为第 4 个元素分配了 5 的 id。
我的理解是
最后一个节点数组有 4 个元素,
这个新的第 4 个元素的索引 i = 3,并且
++i = 4
因此,上述语句应该为第 4 个元素分配了 4 的 id。
但是代码指定了 id=5。当我在 firebug 调试器中检查 i 的值时,i 上升到 4,保持在 4,然后在上述情况下变为 5。
有人可以解释上面的代码发生了什么以及我的错误理解在哪里吗?
谢谢。
【问题讨论】:
-
用 i++ 得到你想要的。
-
不确定我是否理解您的问题。
i是一个全局变量,而不是这里的数组索引,也许这就是你的困惑所在? -
是的,它有一个索引——在函数声明
function(d, i)中明确表示。如果这解决了您的问题,我可以发布一个带有更多解释的答案。 -
谢谢,这解释了我的问题。我原以为 i 是一个特殊的 d3 变量,因为它在 # selection.data([values[, key]]) 段中的github.com/mbostock/d3/wiki/Selections#wiki-data 中说“要控制数据如何连接到元素,可以指定一个键函数. 这替换了默认的按索引行为;key 函数为新数据数组中的每个元素调用一次,并为选择中的每个现有元素调用一次。在这两种情况下,key 函数都传递了数据 d 和索引一世。”这 i 与全局 i 有什么不同吗?谢谢。
-
这是糟糕的编码风格,仅此而已,当我们习惯于在与本地索引变量类似的上下文中看到它时,使用
i作为持久计数器变量。正如@LarsKotthoff 所说,使用的i版本取决于函数声明——如果你声明一个具有特定名称的函数参数,它将屏蔽任何具有相同名称的外部变量。但是,我建议给计数器变量一个不同的名称,以免混淆!
标签: javascript arrays d3.js