2017-02-17 17 views
0

Я пытаюсь узнать D3, и мне трудно понять анонимные функции.D3 JS Что означает значение F, переданное анонимной функции?

В следующем примере в нижней части функции (f) возвращается значение, которое возвращает переменную «интерполировать» с параметром f (который, по моему мнению, является akward, поскольку «интерполяция» не является функцией, переменная).

Но в чем смысл F? Я не вижу, как и где он используется в функции «интерполяция». Если я удалю F и просто пройду(), моя анимация сломается.

Спасибо! :)

svg.append('path') 
     .attr('class', 'line') 
     .attr('d', line(lineData)) 
     .transition() 
     .duration(3000) 
     .attrTween('d', pathTween); 

    function pathTween() { 
     var interpolate = d3.scale.quantile() 
       .domain([0,1]) 
       .range(d3.range(0, 7)); 
     return function(f) { 
      return line(lineData.slice(0, interpolate(f))); 
     }; 
    } 
+0

Ваш 'pathTween()' создает функцию, которая отправляется на d3. В какой-то момент d3 решает вызвать вашу функцию и передать ей один параметр - 'f'. – Sirko

+1

Не совсем относится к D3, но Js в общем, вы можете взглянуть на [что за закрытие] (http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) и как это работает. Убедитесь, что вы понимаете, что происходит, когда функция возвращает другую функцию, которая принимает параметр., Как в этом случае. – Nobita

+0

@Nobita Он специфичен для 'D3', так как все сводится к тому, что' d3.scale.quantile' возвращает функцию, для которой 'f' будет находиться между 0 и 1 в течение всего анимации. Тогда переменная 'interpolate' преобразует числа в соответствующий диапазон. – Ian

ответ

3

Давайте разберем это вниз:

.... 
.attrTween('d', pathTween); 

function pathTween() { 
    var interpolate = d3.scale.quantile() 
      .domain([0,1]) 
      .range(d3.range(0, 7)); 
    return function(f) { 
     return line(lineData.slice(0, interpolate(f))); 
    }; 
} 
  1. Мы передаем функцию закрытия pathTween к attrTween. Под капотом d3 будет вызывать pathTween для каждого элемента в вашем выборе (в вашем случае это всего лишь один path).
  2. d3 ожидает, что функция передана в attrTween, чтобы вернуть функцию. Это анонимная функция, которая принимает параметр f (большинство примеров d3 будут использовать переменную t, более того, в секунду).
  3. Функция pathTween является закрытием, потому что она создает внутреннюю переменную interpolate и закрывает ее, чтобы она была доступна во внутренней возвращенной функции. Вы указали it returns the variable "interpolate" with the parameter f (which i think is itself awkward, since "interpolate" is not a function but a variable). Это неправда; во-первых, мы не возвращаем interpolate вообще (но он доступен в закрытии), а во-вторых, это функция , которая хранится в переменной. Хранение функций в переменных очень распространено в JavaScript (и многие другие языки программирования тоже).
  4. Теперь, когда d3 имеет функцию внутреннего анона, он будет называть его для каждого тика анимации (обычно каждые 16 мс). Когда он назовет его, он пройдет в f. Что такое f? Это таймер (почему его обычно называют t). Он будет содержать значение от 0 до 1, которое указывает, где оно находится при переходе (0 - начало, 1 - в конце). Затем эта переменная передается в функцию interpolate, которая, как ожидается, ожидает от 0 до 1 (см. domain[0,1]).

Проверьте это:

var interpolate = d3.scale.quantile() 
 
       .domain([0,1]) 
 
       .range(d3.range(0, 7)); 
 
       
 
console.log(typeof(interpolate)); 
 

 
console.log(interpolate(0)); 
 
console.log(interpolate(0.25)); 
 
console.log(interpolate(0.5)); 
 
console.log(interpolate(1));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

1

В javascript функции могут передаваться в переменной! https://en.wikipedia.org/wiki/First-class_function

var interpolate = d3.scale.quantile() 
       .domain([0,1]) 
       .range(d3.range(0, 7)); 

в этой линии, D3 создает новую функцию для вас, и затем присваивается переменной interpolate готова быть выполнена в более позднее время

return function(f) { 
      return line(lineData.slice(0, interpolate(f))); 
     }; 

Это затем возвращает функцию, которая может вызывать D3. Когда D3 вызывает эту функцию, она передает значение f, которое ваша функция интерполяции может использовать как вход. Удаление f означало бы вместо этого значение undefined.

+0

На самом деле вы не объясняете, что такое параметр 'f', на котором я задаю вопрос. – Ian

+0

Простите, прошло некоторое время с тех пор, как я использовал D3. Думал, что это все еще стоит, поскольку OP казался, что их больше всего смущало про передачу функций вокруг. Принятый ответ намного лучше, чем мой _b – dpix