2

このJavaScriptコードがどのように機能するかを理解するのに苦労しています。私はJSを学んでおり、以前は動的で関数型の言語に触れていませんでした。そこで、関数呼び出しをビット手続き型の階層順に視覚化します。d3.jsを使用すると、ここで説明するようにsvg要素を描画できます。


var dataset = [ 5, 10, 15, 20, 25 ];

d3.select("body").selectAll("p")
    .data(dataset)
    .enter()
    .append("p")
    .text("New paragraph!");

最後の行を変更しましょう:

.text(function(d) { return d; });

このデモページで新しいコードの機能を確認してください。

うわあ!data()メソッドの魔法のおかげで、データを使用して各段落のコンテンツを入力しました。メソッドをチェーン化すると、data()を呼び出した後はいつでも、dを入力として受け入れる無名関数を作成できます。魔法のdata()メソッドは、現在の要素が手元にある場合、dが元のデータセットの対応する値に設定されることを保証します。


上記のこの魔法は、私が理解できないことです。「d」はグローバル変数ではありません。別の(c)名に変更した場合でも、機能します。したがって、dataメソッドは匿名fnの値を設定している可能性があります。

ただし、現在の関数がオブジェクトを返し、そのオブジェクトで次のメソッドを呼び出すことができるため、通常は(私の限られた読み取りで)連鎖が可能です。上記の場合、dataメソッドはテキスト(「新しい段落!」)がユーザーによって渡されたかどうかをどのように認識しますか。そうでない場合は、データを匿名のfnに渡します。疑問は、textメソッドがダウンラインにあり、data()すでに実行されていることです。データはどのように無名関数に渡されますか?

ありがとう。

4

2 に答える 2

3

d3.jsの内部textを掘り下げると、関数について次の結果が表示されます。

d3_selectionPrototype.text = function(value) {
  return arguments.length < 1
      ? this.node().textContent : this.each(typeof value === "function"
      ? function() { var v = value.apply(this, arguments); this.textContent = v == null ? "" : v; } : value == null
      ? function() { this.textContent = ""; }
      : function() { this.textContent = value; });
};

指定された引数が関数の場合、次のコードが実行されます。

this.each(function() {
    var v = value.apply(this, arguments);  // executing function provided
    this.textContent = v == null ? "" : v;
});

関数eachは次のように宣言されます:

d3_selectionPrototype.each = function(callback) {
  for (var j = -1, m = this.length; ++j < m;) {
    for (var group = this[j], i = -1, n = group.length; ++i < n;) {
      var node = group[i];
      if (node) callback.call(node, node.__data__, i, j); // this is the line you are interested in
    }
  }
  return this;
};  

したがって、呼び出しごとに、からの要素を提供しthisます。そして、それに取り掛かると、関数の呼び出しthisによって移入されます。data

于 2012-06-04T19:53:47.457 に答える
0

ええと、私はこれまでd3を使ったことがありませんが、これは私が理解していることです。

dはデータオブジェクトです(メソッドで設定するdata代わりに呼び出します。ddata()

では、このtext()メソッドは何をしますか?関数を呼び出して、次のような出力を使用しますか?

function text (callback) {
  var theText;
  if (typeof callback === "function") {
    theText = callback(dataset);
  } else {
    theText = callback;
  }
  // does something more
}

したがって、コールバックが関数である場合はそれを呼び出し、その戻り値をテキストとして使用します。

次に、私が推測しているのは、関数が配列の場合、配列内の各要素のテキストメソッドを呼び出すということです。

このようなもの...

function text(callback) {
  var theText;
  if (typeof callback === "function") {
    theText = callback(dataset);
  } else {
    theText = callback;
  }
  if (theText instanceof Array) { // this is not the best way to check if an object is an array, I'll come back to this later. I'm sorry.
    for (var i=0, len=theText.length; i<len; i++) {
      text(theText[i]);
    }
  } else {
    // do something else
  }
  // do something more
}

これは実際に起こることの本当に単純なバージョンになることを考慮に入れてください。

はっきりしない場合はお知らせください。

于 2012-06-04T19:52:24.773 に答える