这段代码:
var force = d3.layout.force()
.nodes(nodes)
.links([])
.size([w, h])
.start();
var
如果它是 C++(关键字除外;在 C++ 中,您必须为 声明一个特定的类型) ,您应该阅读它的基本相同的内容force
。像 C++ 一样,空白(大部分)是微不足道的。每个都.
表示一个属性访问。(与 C++ 不同,JavaScript 对象不区分字段和方法;一切都是属性。如果它是函数属性,则可以通过在名称后面加上括号来调用它——如果合适的话,在括号中加上函数参数。)这里是:
d3.layout
- 访问 的layout
属性d3
。
.force()
- 调用force
作为属性的函数d3.layout
。在里面force
,d3.layout
可以作为关键字使用this
。
.nodes(nodes)
- 调用作为调用nodes
返回的任何对象的属性的函数force()
(也许d3.layout
,也许是别的东西)。
- 等等
最后分配给force
由返回的值start()
。
关于第二段代码:
force.on("tick", function(e) {
// Push different nodes in different directions for clustering.
var k = 6 * e.alpha;
nodes.forEach(function(o, i) {
o.y += i & 1 ? k : -k;
o.x += i & 2 ? k : -k;
});
在这里,我们看到一个示例(实际上是两个)anonymous function
。根据通常的 JavaScript 约定,on
函数force
可能用于注册事件处理程序——在本例中是"tick"
事件处理程序。事件处理程序是匿名函数:
function(e) {
// Push different nodes in different directions for clustering.
var k = 6 * e.alpha;
nodes.forEach(function(o, i) {
o.y += i & 1 ? k : -k;
o.x += i & 2 ? k : -k;
}
为了便于解释,我们称这个函数为“外部”。它需要一个参数,我猜它是一个包含刻度事件属性的对象。在 external 的主体中,我们看到了另一个匿名函数: 的参数nodes.forEach
。让我们称这第二个匿名函数为“内部”。这里的forEach
函数很可能是标准forEach
迭代器函数,它是所有 JavaScript 数组的属性;它接受一个函数作为参数,并按顺序在数组的每个元素上调用该函数,传递数组元素和元素索引。Inner 实际上是一个闭包的例子:函数体引用变量k
,该变量被定义为外部的局部变量。
JavaScript 在某些方面与 C++ 类似,但在某些方面却有着根本的不同。除非您知道相似之处和不同之处的起点,否则您的 C++ 背景可能会导致您在编码(和代码阅读)工作中严重误入歧途。我强烈推荐介绍性论文“A re-introduction to JavaScript”。它涵盖了该语言的所有主要特性,并有助于阐明 C++ 和 JavaScript 的相似之处和不同之处。