Как мне переписать этот код Javascript, чтобы избежать предупреждения JSHint?

Я новичок в разработке небольшого веб-приложения, которое использует HTML, JavaScript (Angular 1.5.0) и CSS. Я использую Grunt для обработки, jslint, минимизации моего javascript и CSS файлов. Мой код Javascript включает изображение SVG, созданное d3.js.

В настоящее время я получаю следующее предупреждение от 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        }

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)
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();
}

Еще один более D3-й подход полностью избавит от внешнего цикла for. Всякий раз, когда вы сталкиваетесь с циклом for вокруг оператора D3, это должно вызывать серьезные подозрения. Чтобы обойти это, вы можете использовать его мощные функции привязки данных:

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: все в данных! Подход использует объекты данных для хранения всей информации о позициях x а также y а также флаг remove который используется, чтобы указать, должен ли текст быть удален на основании некоторого условия. Помимо удаления цикла for, это избавит от некоторых других переменных, таких как myVarX а также myVarY, а также будет интегрировать блок для удаления некоторых элементов.

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)

Отдых выглядит хорошо для меня.

Другие вопросы по тегам