理解 d3.js 源代码:停留在 function.call() 和 “=+”

Understanding d3.js source: stuck at function.call() and "=+"

本文关键字:call js d3 源代码 function 停留在 理解      更新时间:2023-09-26

在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 的新手,无法理解这里发生了什么。

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

又"= +"在这里做什么?

查看 MDN 列表,用于调用、申请和绑定。

这是一个

很难理解的概念,但是在调用和应用中发生的事情是,您选择在不同的"上下文"中执行函数。

我说带引号的"上下文",因为"执行上下文"在JS中具有确切的含义,但事实并非如此。我没有一个很好的词来形容它,但这里发生的事情是,您在执行函数时正在交换this对象。

这可能会有所帮助:

var obj = { foo: "bar" };
method.call( obj, "arg" );
function method( arg ) {
    console.log( this.foo ); #bar
    console.log( arg ); #"arg"
}

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

基本上,它正在转换这个:

function(){ return +new Date; }

进入这个:

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

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

更多关于这方面的阅读

这里

你必须更仔细地遵循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传递为bcundefined)。

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