理解 d3.js 源代码:停留在 function.call() 和 “=+”
Understanding d3.js source: stuck at function.call() and "=+"
在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
传递为a
,y
传递为b
(c
将undefined
)。
+
运算符是一元加运算符 [MDN],它只是将操作数转换为数字。
- 将数据传递给d3.js中的.call
- 为什么要在 Node.js 中使用 util.inherits 和 .call 进行继承
- 理解 d3.js 源代码:停留在 function.call() 和 “=+”
- Authorization for window.location.href call in angular js
- vanilla js vs jQuery ajax call
- Using typeahead.js with jquery ajax call
- 通过 .scope().call() 从 JS 外部调用 Angular 服务会挂起请求
- Ajax call and node.js
- Node.js:事件的关系.EventEmitter.call(this)和Obj.prototype.__proto_
- call()将js对象格式化为正确的rest查询
- 使用JS.call()方法的原因
- 使用js-apply-and-call创建一个webtrend函数来消除重复
- 试图理解 js 中的 Function.prototype.call
- node.js中的回调函数.TypeError: Cannot call method 'emit'的定
- js:为什么用Array.prototype.map.call代替map() ?
- js Array.prototype.filter.call() - 有人可以解释我这段代码是如何工作的
- Angular js $http 404 call WebApi
- Node.js TypeError: Cannot call method 'write' of und
- “什么,call"js中的do函数
- 在扩展THREE.js的“类”时,为什么需要从新对象中调用.call(this)方法?