1

我试图通过弄脏自己的手来理解 javascript 代码。我的背景主要是 python 和 C++。

所以我在这里通过这段代码

http://bl.ocks.org/mbostock/1021841

var force = d3.layout.force()
.nodes(nodes)
.links([])
.size([w, h])
.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;
  });

有人能用更简单的语言把它分解给我吗?谢谢

4

2 回答 2

3

这段代码:

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。在里面forced3.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 的相似之处和不同之处。

于 2013-02-21T08:24:07.157 回答
1

这个:

var force = d3.layout.force()
.nodes(nodes)
.links([])
.size([w, h])
.start();

与此相同:

var force = d3.layout.force().nodes(nodes).links([]).size([w, h]).start();

变量的值force将是链中最后一个方法的返回值(在这种情况下.start())。

这称为方法链。每个连续的函数都作为一个方法调用它之前函数的返回值。

因此,在.nodes(nodes)返回的对象上调用方法,在返回的对象上调用d3.layout.force()方法,依此类推。.links([]).nodes(nodes)

于 2013-02-21T07:31:30.377 回答