简体   繁体   中英

trying to understand javascript code

I am trying to understand javascript code by getting my hands dirty.. My background is mostly python and C++.

So I was going thru this code here

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

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

I am guessing that "." represents a method.. but to which object? and I am having hard time understanding this convoluted function (method??)

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;
  });

Can someone break it down to me in simpler language. Thanks

This code:

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

should be read in basically the same you would read it if it were C++ (except for the var keyword; in C++ you'd have to declare a particular type for force ). Like C++, white space is (mostly) insignificant. Each . indicates a property access. (Unlike C++, JavaScript objects don't distinguish fields from methods; everything is a property. If it's a function property, then it can be called by following the name with parentheses—with function arguments in the parentheses if appropriate.) So what's going on here is:

  • d3.layout - access the layout property of d3 .
  • .force() - invoke the force function that is a property of d3.layout . Inside force , d3.layout would be available as the keyword this .
  • .nodes(nodes) - invoke the nodes function that is a property of whatever object was returned by the call to force() (perhaps d3.layout , perhaps something else).
  • etc.

finally assigning to force the value returned by start() .

Regarding the second piece of code:

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;
  });

Here we see an example (two, actually) of an anonymous function . Based on usual JavaScript conventions, the on function of force is probably used to register an event hander—in this case for the "tick" event. The event handler is the anonymous function:

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;
}

For purposes of explanation, let's call this function "outer". It takes an argument which I would guess is an object containing the properties of the tick event. In the body of outer, we see another anonymous function: the argument to nodes.forEach . Let's call this second anonymous function "inner". The forEach function here is most likely the standard forEach iterator function that is a property of all JavaScript arrays; it takes a function as an argument and invokes the function on every element of the array in sequence, passing the array element and the element index. Inner is actually an example of a closure : the function body references variable k which is defined as a local variable of outer.

JavaScript is in some ways just like C++ and in some ways fundamentally different. Unless you know where the similarities end and the differences begin, your C++ background can lead you seriously astray in your coding (and code reading) efforts. I highly recommend the introductory paper "A re-introduction to JavaScript" . It covers all the major features of the language and should help clarify just how C++ and JavaScript are similar and how they are different.

This:

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

Is the same as this:

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

The value of the variable force will be the return value from the last method in the chain (in this case .start() ).

This is called method chaining. Each successive function is called as a method on the return value of the function before it.

So, the method .nodes(nodes) is called on the object that is returned from d3.layout.force() and the method .links([]) is called on the object returned from .nodes(nodes) and so on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM