Javascript D3.js键函数在简单选择器/数组组合上运行两次

Javascript D3.js键函数在简单选择器/数组组合上运行两次,javascript,d3.js,Javascript,D3.js,学习d3,当我创建一个简单的数字数组,然后尝试将数据绑定到一个简单的元素集时,使用key函数,它会在循环中运行两次。第一次通过时,它告诉我数组的值未定义。第二次通过它们是可用的 以下是html: <div class="testBind"></div> <div class="testBind"></div> <div class="testBind"></div> 当我运行此程序时,我得到: n----:undefine

学习d3,当我创建一个简单的数字数组,然后尝试将数据绑定到一个简单的元素集时,使用key函数,它会在循环中运行两次。第一次通过时,它告诉我数组的值未定义。第二次通过它们是可用的

以下是html:

<div class="testBind"></div>
<div class="testBind"></div>
<div class="testBind"></div>
当我运行此程序时,我得到:

n----:undefined
n----:undefined
n----:undefined
n----:1
n----:2
n----:3
这是一个小提琴手:

这是一个问题(除了wtf之外)的原因是,当数据是一个对象数组并且我尝试引用函数中的键时,它会抛出一个未定义的错误。

来自d3帮助:

可以指定一个键函数来控制数据如何连接到元素。这将替换默认的索引行为;对新数据数组中的每个元素调用一次key
函数,对所选内容中的每个现有元素调用一次key
。在这两种情况下,键函数都传递给基准d和索引i。当在新的数据元素上对关键函数求值时,此上下文的上下文是数据数组;在现有选择上计算键函数时,此上下文是关联的DOM元素


您在第一个循环中看到的是通过现有数据(没有),然后通过新的数据数组(具有您期望的值)。如果键函数依赖于某个对象,则需要先进行检查以确保该对象存在

我发现了一个很好的解释,说明了selectAll如何在页面上没有任何元素的情况下创建虚拟选择,但这仍然没有回答上述问题。为什么它对每个实际元素循环一次,但不应用数据?我们还找到了一个解释,说明了在使用对象数组时如何绕过它:但这仍然不能解释这里发生了什么或为什么。在这里,我可以在循环中看到各种值。因此,如果第二次循环的目的是返回要绑定到元素的数据,那么将“this”设置为现有元素的第一次循环的目的是什么?d3确定哪些元素已插入、哪些元素已更新、哪些元素已删除。因为索引函数可以是动态的,所以它会在现有数据和新数据上运行它,以确定它应该如何进行连接。对新数据执行
.enter()
,对删除的数据执行
.exit()
n----:undefined
n----:undefined
n----:undefined
n----:1
n----:2
n----:3