1

在d3.layout.force的源码中,第158行,有这段代码

force.charge = function(x) {
    if (!arguments.length) return charge;
    charge = typeof x === "function" ? x : +x;
    return force;
};

现在,如果你转到第 225 行,你会看到

charges = [];
if (typeof charge === "function") {
  for (i = 0; i < n; ++i) {
    charges[i] = +charge.call(this, nodes[i], i);
  }
} else {
  for (i = 0; i < n; ++i) {
    charges[i] = charge;
  }
}

我在这里不明白的是这条线

charges[i] = +charge.call(this, nodes[i], i);

我是 JavaScript 新手,无法理解这里发生了什么。

据我了解,charge 只需要 1 个参数 ( x)。这里“ this”被传递给当前对象的上下文,但其他两个呢?nodes[i]" " 和 " " 中的哪一个i被视为 " x" ?

又是什么“ = +”在这里做什么?

4

3 回答 3

1

查看 MDN 列表中的callapplybind

这是一个很难理解的概念,但在 call 和 apply 中发生的事情是你选择在不同的“上下文”中执行一个函数。

我说带有引号的“上下文”作为“执行上下文”在 JS 中具有确切的含义,但这不是。我没有一个很好的词,但这里发生的事情是您在this执行函数时正在换出对象。

这可能会有所帮助:

var obj = { foo: "bar" };
method.call( obj, "arg" );
function method( arg ) {
    console.log( this.foo ); #bar
    console.log( arg ); #"arg"
}
于 2012-05-31T22:52:49.970 回答
1

我想你会在这里找到你的答案。

基本上,它正在转换:

function(){ return +new Date; }

进入这个:

function(){ return Number(new Date); }

本质上,它将参数转换为数字,并将其添加到先前的值。

更多关于这里的阅读

于 2012-05-31T22:53:11.680 回答
0

你必须charge更仔细地跟随。它是第 11 行中定义的变量:

charge = -30,

您引用的功能force.charge设置费用,它不是中提到的功能+charge.call(this, nodes[i], i);。看看第二行force.charge

charge = typeof x === "function" ? x : +x;

x可以是传递的函数(回调),以动态计算费用。当前节点 ( nodes[i]) 和节点 ( ) 的索引i将传递给此回调,以便您可以根据这些值动态计算费用:

force.charge(function(node, index) {
    return index * 2;
});

x(因此charge)也可以是数字或数字字符串。这就是为什么要预先测试它是否charge是一个函数:

if (typeof charge === "function") {
  // function so we call it and pass the current node and index
} else {
  // static value, the same for each node
}

因此,您始终可以将任意数量的参数传递给函数,无论它定义了多少参数。例如:

function foo() {
    alert([].join.call(null, arguments));
}

foo('a', 'b');

会提醒a,b


回答您的问题:传递给.call() [MDN].apply() [MDN]的参数以相同的顺序传递给函数。因此,如果我有一个函数function foo(a, b, c),那么foo.call(null, x, y)x作为ay作为bc将是undefined)传递。

+运算符是一元加运算[MDN],它只是将操作数转换为数字。

于 2012-05-31T22:56:49.733 回答