jslint工具的一个提示是:

++和—— ++(递增)和——(递减) 众所周知,操作符会导致糟糕的代码 鼓励过度狡诈。他们 仅次于有缺陷的架构 使病毒和其他 安全威胁。这是一个加分项 选项,禁止使用这些 操作符。

我知道PHP结构像$foo[$bar++]可能很容易导致off-by-one错误,但我想不出一个更好的方法来控制循环比:

while( a < 10 ) do { /* foo */ a++; }

or

for (var i=0; i<10; i++) { /* foo */ }

jslint突出显示它们是因为有一些类似的语言缺少“++”和“——”语法或处理方式不同,还是有其他避免“++”和“——”的理由,我可能忽略了?


当前回答

在作为前缀和后缀使用时,操作符的含义不同,这可能会导致难以发现的错误。考虑下面的例子,使用bubbleSort:

function bubbleSort(array) {
  if(array.length === 1) return array;

  let end = array.length - 2;
  do {
    for (let i = 0; i < array.length; i += 1) {
      if (array[i] > array[i + 1]) {
        swap(array, i, i + 1);
      }
    }
  } while (end--);
}

bubbleSort([6,5]);

让我们想象一下,在运行程序的过程中,我们将一个包含两项的值传递给排序函数。代码按原样运行很好:“do/while”循环在达到条件之前首先执行。然而,程序认为结束是假的,并在变量递减之前退出循环。

现在考虑下面的代码,其中——符号用作前缀,而不是后缀。这段代码将进入一个无限循环:

function bubbleSort(array) {
  if(array.length === 1) return array;

  let end = array.length - 2;
  do {
    for (let i = 0; i < array.length; i += 1) {
      if (array[i] > array[i + 1]) {
        swap(array, i, i + 1);
      }
    }
  } while (--end);
}

bubbleSort([6,5]);

现在,当我们达到while条件时,我们在检查它之前递减结束值。返回-1,这在Javascript中是一个真值。

我对它们的使用方式没有强烈的意见,但我只是想说明,如果不小心使用它们,它们会导致真正的错误。

其他回答

在作为前缀和后缀使用时,操作符的含义不同,这可能会导致难以发现的错误。考虑下面的例子,使用bubbleSort:

function bubbleSort(array) {
  if(array.length === 1) return array;

  let end = array.length - 2;
  do {
    for (let i = 0; i < array.length; i += 1) {
      if (array[i] > array[i + 1]) {
        swap(array, i, i + 1);
      }
    }
  } while (end--);
}

bubbleSort([6,5]);

让我们想象一下,在运行程序的过程中,我们将一个包含两项的值传递给排序函数。代码按原样运行很好:“do/while”循环在达到条件之前首先执行。然而,程序认为结束是假的,并在变量递减之前退出循环。

现在考虑下面的代码,其中——符号用作前缀,而不是后缀。这段代码将进入一个无限循环:

function bubbleSort(array) {
  if(array.length === 1) return array;

  let end = array.length - 2;
  do {
    for (let i = 0; i < array.length; i += 1) {
      if (array[i] > array[i + 1]) {
        swap(array, i, i + 1);
      }
    }
  } while (--end);
}

bubbleSort([6,5]);

现在,当我们达到while条件时,我们在检查它之前递减结束值。返回-1,这在Javascript中是一个真值。

我对它们的使用方式没有强烈的意见,但我只是想说明,如果不小心使用它们,它们会导致真正的错误。

对于不熟悉自增和自减操作符的人来说,它们的“前”和“后”性质容易让人感到困惑;这是它们可能很棘手的一种方式。

我的观点是在一行中单独使用++和——,如下所示:

i++;
array[i] = foo;

而不是

array[++i] = foo;

在我看来,任何超出这个范围的事情都会让一些程序员感到困惑。For循环是一个例外,因为增量操作符的使用是惯用的,因此总是明确的。

我认为程序员应该精通他们所使用的语言;清楚地使用它;好好利用它。我认为他们不应该人为地削弱他们正在使用的语言。这是我的经验之谈。我曾经在一家Cobol商店的隔壁工作,他们不使用ELSE“因为它太复杂了”。荒谬还原。

另一个例子,比其他一些简单的递增值返回更简单:

function testIncrement1(x) {
    return x++;
}

function testIncrement2(x) {
    return ++x;
}

function testIncrement3(x) {
    return x += 1;
}

console.log(testIncrement1(0)); // 0
console.log(testIncrement2(0)); // 1
console.log(testIncrement3(0)); // 1

如您所见,如果希望此操作符影响结果,则不应在return语句中使用后递增/递减操作。但是return不会“捕获”自增/自减操作符:

function closureIncrementTest() {
    var x = 0;

    function postIncrementX() {
        return x++;
    }

    var y = postIncrementX();

    console.log(x); // 1
}