jslint工具的一个提示是:

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

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

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

or

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

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


当前回答

我一直在看Douglas Crockford关于这个的视频他对不使用递增和递减的解释是

在过去的其他语言中,它被用来打破数组的界限,并导致各种各样的坏和 它更令人困惑,没有经验的JS开发人员不知道它到底是做什么的。

首先,JavaScript中的数组是动态大小的,因此,如果我说错了,请原谅我,在JavaScript中使用这种方法不可能打破数组的界限并访问不应该访问的数据。

其次,我们是否应该避免那些复杂的东西,当然问题不在于我们有这个工具,而在于有些开发者声称要做JavaScript,但不知道这些操作符是如何工作的?这很简单。Value ++,给我当前的值,在表达式之后加1,++ Value,在给我它之前增加值。

像a ++ + ++ b这样的表达式,只要记住上面的内容,就很容易计算出来。

var a = 1, b = 1, c;
c = a ++ + ++ b;
// c = 1 + 2 = 3; 
// a = 2 (equals two after the expression is finished);
// b = 2;

我想你只需要记住谁需要通读代码,如果你有一个对JS了如指掌的团队,那你就不用担心了。如果不是,那么评论它,以不同的方式写它,等等。做你该做的。我不认为递增和递减本身就不好,或者产生错误,或者产生漏洞,可能只是根据你的读者的不同,可读性更差。

顺便说一句,我认为道格拉斯·克罗克福德是一个传奇,但我认为他引起了很多恐慌,因为他是一个不值得的操作员。

我活着就是为了证明我是错的……

其他回答

在循环中,它是无害的,但在赋值语句中,它会导致意想不到的结果:

var x = 5;
var y = x++; // y is now 5 and x is 6
var z = ++x; // z is now 7 and x is 7

变量和操作符之间的空格也会导致意想不到的结果:

a = b = c = 1; a ++ ; b -- ; c; console.log('a:', a, 'b:', b, 'c:', c)

在闭包中,意外的结果也可能是一个问题:

var foobar = function(i){var count = count || i; return function(){return count++;}}

baz = foobar(1);
baz(); //1
baz(); //2


var alphabeta = function(i){var count = count || i; return function(){return ++count;}}

omega = alphabeta(1);
omega(); //2
omega(); //3

它会自动在换行后插入分号:

var foo = 1, bar = 2, baz = 3, alpha = 4, beta = 5, delta = alpha
++beta; //delta is 4, alpha is 4, beta is 6

增量前/增量后的混淆会产生差一的错误,这很难诊断。幸运的是,它们也是完全不必要的。给变量加1有更好的方法。

参考文献

JSLint帮助:增加和减少操作符

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

在作为前缀和后缀使用时,操作符的含义不同,这可能会导致难以发现的错误。考虑下面的例子,使用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中是一个真值。

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

我一直在看Douglas Crockford关于这个的视频他对不使用递增和递减的解释是

在过去的其他语言中,它被用来打破数组的界限,并导致各种各样的坏和 它更令人困惑,没有经验的JS开发人员不知道它到底是做什么的。

首先,JavaScript中的数组是动态大小的,因此,如果我说错了,请原谅我,在JavaScript中使用这种方法不可能打破数组的界限并访问不应该访问的数据。

其次,我们是否应该避免那些复杂的东西,当然问题不在于我们有这个工具,而在于有些开发者声称要做JavaScript,但不知道这些操作符是如何工作的?这很简单。Value ++,给我当前的值,在表达式之后加1,++ Value,在给我它之前增加值。

像a ++ + ++ b这样的表达式,只要记住上面的内容,就很容易计算出来。

var a = 1, b = 1, c;
c = a ++ + ++ b;
// c = 1 + 2 = 3; 
// a = 2 (equals two after the expression is finished);
// b = 2;

我想你只需要记住谁需要通读代码,如果你有一个对JS了如指掌的团队,那你就不用担心了。如果不是,那么评论它,以不同的方式写它,等等。做你该做的。我不认为递增和递减本身就不好,或者产生错误,或者产生漏洞,可能只是根据你的读者的不同,可读性更差。

顺便说一句,我认为道格拉斯·克罗克福德是一个传奇,但我认为他引起了很多恐慌,因为他是一个不值得的操作员。

我活着就是为了证明我是错的……

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