D3 JS 传递给匿名函数的F是什么意思?

D3 JS Whats the meaning of the F passed to the anonymous function?

我正在努力学习 D3,但我很难理解匿名函数。

在下面的示例中,底部有一个函数(f),它 returns returns 变量 "interpolate" 带有参数 f(我认为它本身很尴尬,因为 "interpolate" 不是一个函数,而是一个变量)。

但是F是什么意思呢?我没有看到它在 "interpolate" 函数中的使用方式或位置。如果我删除 F 并只传递 (),我的动画就会中断。

谢谢! :)

svg.append('path')
        .attr('class', 'line')
        .attr('d', line(lineData))
        .transition()
        .duration(3000)
        .attrTween('d', pathTween);

    function pathTween() {
        var interpolate = d3.scale.quantile()
                .domain([0,1])
                .range(d3.range(0, 7));
        return function(f) {
            return line(lineData.slice(0, interpolate(f)));
        };
    }

在javascript中,函数可以在变量中传递! https://en.wikipedia.org/wiki/First-class_function

var interpolate = d3.scale.quantile()
                .domain([0,1])
                .range(d3.range(0, 7));

在这一行中,D3 为您创建了一个新函数,然后将其分配给变量interpolate 准备稍后执行

return function(f) {
            return line(lineData.slice(0, interpolate(f)));
        };

这就是returns一个可以被D3调用的函数。当 D3 调用此函数时,它会为 f 传递一个值,您的插值函数可以将其用作输入。删除 f 意味着将值 undefined 传递给函数。

让我们分解一下:

....
.attrTween('d', pathTween);

function pathTween() {
    var interpolate = d3.scale.quantile()
            .domain([0,1])
            .range(d3.range(0, 7));
    return function(f) {
        return line(lineData.slice(0, interpolate(f)));
    };
}
  1. 我们正在将闭包函数 pathTween 传递给 attrTween。在引擎盖下 d3 将为您选择的每个元素调用 pathTween(在您的情况下它只是一个 path)。
  2. d3 期望传递给 attrTween 的函数为 return 一个函数。这是采用参数 f 的匿名函数(大多数 d3 示例将使用变量 t,稍后会详细介绍)。
  3. pathTween 函数是一个闭包,因为它创建了内部 变量 interpolate 并将其关闭,以便它在内部 returned 函数。你说 it returns the variable "interpolate" with the parameter f (which i think is itself awkward, since "interpolate" is not a function but a variable)。这不是真的;首先,我们根本没有 return interpolate(但它在闭包中可用),其次,它是一个 函数,存储在一个变量 .在变量中存储函数在 JavaScript(以及许多其他编程语言)中非常常见。
  4. 现在 d3 具有内部 anon 函数,它将在动画的每个滴答声中调用它(通常每 16 毫秒)。当它调用它时,它会传入 f。什么是 f?它是一个计时器(为什么它通常被称为 t)。它将包含一个从 0 到 1 的值,指示它在转换中的位置(0 是开始,1 是结束)。然后将该变量传递给 函数 interpolate,它恰好需要一个介于 0 和 1 之间的值(参见 domain[0,1])。

看看这个:

var interpolate = d3.scale.quantile()
                .domain([0,1])
                .range(d3.range(0, 7));
                
console.log(typeof(interpolate));

console.log(interpolate(0));
console.log(interpolate(0.25));
console.log(interpolate(0.5));
console.log(interpolate(1));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>