2017-02-17 45 views
0

我想學習D3,我很難理解匿名函數。D3 JS F傳遞給匿名函數的含義是什麼?

在下面的例子中,在函數底部有一個函數(f),它返回的參數爲f(我認爲它本身是有問題的,因爲「interpolate」不是一個函數,而是一個函數變量)。

但是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沒有嚴格關係,但總的來說,你可能想看看[什麼是閉包](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. 我們是路過的閉合功能pathTweenattrTween。在引擎蓋下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

相關問題