2016-04-27 46 views
1

我是一個開發小型Web應用程序的新手,使用HTML,JavaScript(Angular 1.5.0)& CSS。我正在使用Grunt來處理jslint,縮小我的JavaScript和CSS文件。我的Javascript代碼包含由d3.js創建的SVG圖像。如何重寫此Javascript代碼以避免JSHint警告?

我目前正從jshint以下警告:

line 1932 col 32 Don't make functions within a loop. 

我怎麼可以重寫下面的代碼,以消除此警告?

Line #1924  for (var j = 0; j <= 5; j++) { 
Line #1925   var myVarX = j * 100; 
Line #1926   var myVarY = j * 200; 
Line #1927   var myText = self.svgContainer.append("text") 
Line #1928   .attr("x", myVarX) 
Line #1929   .attr("y", myVarY) 
Line #1930   .text("Hello World") 
Line #1931   .attr("fill", "black") 
Line #1932   .attr("transform", function(d){ 
Line #1933    var bb = this.getBBox(); 
Line #1934    leftBoundary = bb.x + (bb.width/(-2)); 
Line #1935    return "translate(" + (bb.width/(-2)) + ", 0)"; 
Line #1936    } 
Line #1937   ) 
Line #1938   if (leftBoundary > centerX + 5) 
Line #1939   myText.style("display", "block"); 
Line #1940   else 
Line #1941   myText.remove(); 
Line #1942  } 
+3

在循環外定義它並使用'.attr('transform',NAMEOFYOURFUNCTION)'調用它。 – str

+1

jshint thows警告,因爲每個循環迭代新函數都被創建,並且它對性能有不同的影響。 @str有權利,只需在循環範圍外定義此函數,並將其稱爲 –

回答

4

移動此

function(d){ 
    var bb = this.getBBox(); 
    leftBoundary = bb.x + (bb.width/(-2)); 
    return "translate(" + (bb.width/(-2)) + ", 0)"; 
} 

的for循環的範圍之外。像:

var transformCallback = function(d) { 
    var bb = this.getBBox(); 
    ... 

然後用transformCallback代替該功能。

.attr("transform", transformCallback) 
+0

或者只是使用loopfunc選項忽略該消息: – codetoshare

+1

@codetoshare該消息是有原因的。你應該避免在循環中定義函數,因爲在上面的例子中,每次循環迭代都會創建一個新的匿名函數,但實際上只有一個函數就足夠了。 –

+0

@AdarshKonchady,我的評論是斯蒂芬答案的補充。我知道消息的存在。 – codetoshare

1
Function.prototype.getTransform = function() { 
    var bb = this.getBBox(); 
    leftBoundary = bb.x + (bb.width/(-2)); 
    return "translate(" + (bb.width/(-2)) + ", 0)"; 
}; 

... 

for (var j = 0; j <= 5; j++) { 
    var myVarX = j * 100; 
    var myVarY = j * 200; 
    var myText = self.svgContainer.append("text") 
    .attr("x", myVarX) 
    .attr("y", myVarY) 
    .text("Hello World") 
    .attr("fill", "black") 
    .attr("transform", this.getTransform()) 
    if (leftBoundary > centerX + 5) 
    myText.style("display", "block"); 
    else 
    myText.remove(); 
} 
+4

最好避免修改內置的'Function'原型。 –

+0

是的offcourse。我的例子是面向對象的方法,其中'Function'應該被他的「class」所取代。 –

0
Line 1924 : Change `j++` to `j+=1` 
Line 1932: Take out the function def outside the loop. Define it outside and use it here 

// function defined outside the loop 
function transformFn(d) { 
    var bb = this.getBBox(); // if using jQuery replace this with $(this) or that/self to ensure correct this binding 
    leftBoundary = bb.x + (bb.width/(-2)); 
    return "translate(" + (bb.width/(-2)) + ", 0)"; 
} 


// function used at Line1932 
.attr('transform', transformFn) 

休息對我來說很好。

1

另外更多D3- ish方法將完全擺脫外部for-loop。每當你遇到圍繞D3聲明的for循環時,這都會引起嚴重的懷疑。爲了避免這一點,你可以使用其強大的數據綁定功能:

d3.selectAll("text") 
    .data(d3.range(6).map(function(d) {   // data binding replaces for-loop 
    return { 
     x: d * 100, 
     y: d * 200, 
     remove: false       // used to mark the texts for removal 
    }; 
    }))        
    .enter().append("text") 
    .text("Hello World") 
    .attr("x", function(d) { return d.x; }) // replaces myVarX 
    .attr("y", function(d) { return d.y; }) // replaces myVarY 
    .attr("fill", "black") 
    .attr("transform", function(d){ 
     var bb = this.getBBox(); 
     // mark texts for removal based on the condition 
     d.remove = (bb.x + (bb.width/(-2))) <= centerX + 5; 
     return "translate(" + (bb.width/(-2)) + ", 0)"; 
    }) 
    .style("display", "block") 
    .filter(function(d) { return d.remove; }) // select all texts marked for removal 
    .remove(); 

這是一個純粹的D3將採取的方式:它的所有數據!該方法使用數據對象來保存位置xy的所有信息以及標記remove,該標記用於指示是否基於某些條件來刪除文本。除了去除for循環之外,這將除去一些其他變量,如myVarXmyVarY,並且還將整合該塊去除一些元素。