In the source code of d3.layout.force, line 158, there is this code
force.charge = function(x) {
if (!arguments.length) return charge;
charge = typeof x === "function" ? x : +x;
return force;
};
Now, if you go to line 225, you will see
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;
}
}
What I did not understand here is the line
charges[i] = +charge.call(this, nodes[i], i);
I am new to JavaScript and can not understand what’s going on here.
As far as I understood charge takes only 1 argument (x). Here “this” is passed to give the context of current object but what about the other two? Which one of “nodes[i]” and “i” is taken as “x” ?
Again what is “= +” doing here?
You have to follow
chargemore carefully. It is variable defined in line 11:The function
force.chargewhich you quoted is for setting the charge, it is not the function referred to in+charge.call(this, nodes[i], i);. Have a look at the second line offorce.charge:xcan be a function (callback) you pass, to dynamically calculate the charge. The current node (nodes[i]) and the index of the node (i) will be passed to this callback, so that you can calculate the charge dynamically based on these values:x(and thereforecharge) can also be a number or numerical string. That’s why it is tested beforehand whetherchargeis a function or not:Apert from that, you can always pass any number of arguments to a function, no matter how many parameters it has defined. For example:
will alert
a,b.To answer your questions: The arguments passed to
.call()[MDN] or.apply()[MDN] are passed in the same order to the function. So if I have a functionfunction foo(a, b, c)thenfoo.call(null, x, y)would passxasaandyasb(cwould beundefined).The
+operator is the unary plus operator [MDN], which simply converts the operand into a number.