【问题标题】:How do I re-write this Javascript code to avoid JSHint warning?如何重新编写此 Javascript 代码以避免 JSHint 警告?
【发布时间】:2016-08-21 05:24:55
【问题描述】:

我是一个新手,正在开发一个使用 HTML、JavaScript (Angular 1.5.0) 和 CSS 的小型 Web 应用程序。我正在使用 Grunt 来处理、jslint、缩小我的 javascript 和 CSS 文件。我的 Javascript 代码包含由 d3.js 创建的 SVG 图像。

我目前从 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        }

【问题讨论】:

  • 在循环外定义它并使用.attr('transform', NAMEOFYOURFUNCTION)调用它。
  • jshint 会发出警告,因为每次循环迭代都会创建新函数,并且它对性能的影响很大。 @str 是对的,只要在循环范围之外定义这个函数,然后调用它

标签: javascript angularjs d3.js jshint grunt-contrib-jshint


【解决方案1】:

移动一下

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)

【讨论】:

  • 或者使用 loopfunc 选项忽略该消息:
  • @codetoshare 该消息的存在是有原因的。您应该避免在循环中定义函数,因为在上述情况下,每次循环迭代都会创建一个新的匿名函数,而实际上,只有 1 个函数就足够了。
  • @AdarshKonchady,我的评论是对斯蒂芬回答的补充。我知道消息的存在。
【解决方案2】:
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();
}

【讨论】:

  • 最好避免修改内置的Function原型。
  • 是的。我的示例是针对更面向对象的方法,其中应将 Function 替换为他的“类”。
【解决方案3】:

另一种 D3-ish 方法将完全摆脱外部 for 循环。每当您遇到围绕 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,并且还将整合用于移除部分元素的块。

【讨论】:

    【解决方案4】:
    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)
    

    我觉得休息很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-30
      • 2011-03-22
      • 2021-05-09
      相关资源
      最近更新 更多