天天看点

为什么要避免使用JavaScript中的递增(“++”)和递减(“ - ”)运算符?

本文翻译自:Why avoid increment (“++”) and decrement (“--”) operators in JavaScript?

One of the tips for jslint tool is:

jslint工具的一个提示是:
++ and -- ++和 - The ++ (increment) and -- (decrement) operators have been known to contribute to bad code by encouraging excessive trickiness. 已知++(递增)和 - (递减)运算符通过鼓励过多的诡计来导致错误的代码。 They are second only to faulty architecture in enabling to viruses and other security menaces. 它们仅次于故障架构,可以实现病毒和其他安全威胁。 There is a plusplus option that prohibits the use of these operators. 有一个加号选项禁止使用这些运算符。

I know that PHP constructs like

$foo[$bar++]

has may easily result with off-by-one errors, but I couldn't figure out a better way to control the loop than a

while( a < 10 ) do { a++; }

我知道像

$foo[$bar++]

这样的PHP构造可能很容易导致一个一个错误,但是我想不出一个更好的方法来控制循环而不是

while( a < 10 ) do { a++; }

while( a < 10 ) do { a++; }

or

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

.

while( a < 10 ) do { a++; }

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

Is the jslint highlighting them because there are some similar languages that lack the "

++

" and "

--

" syntax or handle it differently, or are there other rationales for avoiding "

++

" and "

--

" that I might be missing?

jslint是否突出显示它们是因为有些类似的语言缺少“

++

”和“

--

”语法或者处理方式不同,或者是否有其他理由来避免“

++

”和“

--

”我可能会丢失?

#1楼

参考:https://stackoom.com/question/44gK/为什么要避免使用JavaScript中的递增-和递减-运算符

#2楼

I don't know if this was part of his reasoning, but if you use a poorly-written minification program, it could turn

x++ + y

into

x+++y

.

我不知道这是否是他推理的一部分,但是如果你使用写得不好的缩小程序,它可以将

x++ + y

转换为

x+++y

But then again, a poorly written tool can wreak all kinds of havoc.

但话说回来,写得不好的工具可能会造成各种各样的破坏。

#3楼

In a loop it's harmless, but in an assignment statement it can lead to unexpected results:

在循环中它是无害的,但在赋值语句中它可能导致意外的结果:
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
           

Whitespace between the variable and the operator can lead to unexpected results as well:

变量和运算符之间的空格也会导致意外结果:
a = b = c = 1; a ++ ; b -- ; c; console.log('a:', a, 'b:', b, 'c:', c)
           

In a closure, unexpected results can be an issue as well:

在闭包中,意外的结果也是一个问题:
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
           

And it triggers automatic semicolon insertion after a newline:

它会在换行后触发自动分号插入:
var foo = 1, bar = 2, baz = 3, alpha = 4, beta = 5, delta = alpha
++beta; //delta is 4, alpha is 4, beta is 6
           
preincrement/postincrement confusion can produce off-by-one errors that are extremely difficult to diagnose. preincrement / postincrement confusion可以产生非常难以诊断的错误。 Fortunately, they are also complete unnecessary. 幸运的是,他们也完全没必要。 There are better ways to add 1 to a variable. 有更好的方法可以将1添加到变量中。

References

参考
  • JSLint Help: Increment and Decrement Operators JSLint帮助:递增和递减运算符

#4楼

Another example, more simple than some others with simple return of incremented value:

另一个例子,比其他一些简单返回递增值更简单:
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
           

As you can see, no post-increment/decrement should be used at return statement, if you want this operator to influence the result.

如您所见,如果您希望此运算符影响结果,则不应在return语句中使用后递增/递减。

But return doesn't "catch" post-increment/decrement operators:

但是返回不会“捕获”后递增/递减运算符:
function closureIncrementTest() {
    var x = 0;

    function postIncrementX() {
        return x++;
    }

    var y = postIncrementX();

    console.log(x); // 1
}
           

#5楼

In my experience, ++i or i++ has never caused confusion other than when first learning about how the operator works.

根据我的经验,除了第一次了解运算符的工作原理之外,++ i或i ++从未引起混淆。

It is essential for the most basic for loops and while loops that are taught by any highschool or college course taught in languages where you can use the operator.

它对于最基本的for循环和while循环来说是必不可少的,这些循环由任何高中或大学课程教授,用您可以使用操作员的语言进行教学。

I personally find doing something like what is below to look and read better than something with a++ being on a separate line.

我个人觉得做的事情就像下面的内容一样,看起来和阅读比单独一行的++更好。

In the end it is a style preference and not anything more, what is more important is that when you do this in your code you stay consistent so that others working on the same code can follow and not have to process the same functionality in different ways.

最后,它是一种风格偏好,而不是更多,更重要的是,当你在代码中执行此操作时,您保持一致,以便其他使用相同代码的人可以遵循而不必以不同方式处理相同的功能。

Also, Crockford seems to use i-=1, which I find to be harder to read than --i or i--

另外,Crockford似乎使用i- = 1,我发现它比--i或i--更难阅读

#6楼

I've been watching Douglas Crockford's video on this and his explanation for not using increment and decrement is that

我一直在观看道格拉斯·克罗克福德关于此的​​视频,他对不使用增量和减量的解释就是这样
  1. It has been used in the past in other languages to break the bounds of arrays and cause all manners of badness and 过去在其他语言中使用它来打破数组的界限并导致所有的不良行为
  2. That it is more confusing and inexperienced JS developers don't know exactly what it does. 更令人困惑和缺乏经验的JS开发人员并不确切知道它的作用。

Firstly arrays in JavaScript are dynamically sized and so, forgive me if I'm wrong, it is not possible to break the bounds of an array and access data that shouldn't be accessed using this method in JavaScript.

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

Secondly, should we avoid things that are complicated, surely the problem is not that we have this facility but the problem is that there are developers out there that claim to do JavaScript but don't know how these operators work??

其次,如果我们避免复杂的事情,问题肯定不是我们有这个设施,但问题是那里有开发人员声称做JavaScript而不知道这些操作符是如何工作的?

It is simple enough.

这很简单。

value++, give me the current value and after the expression add one to it, ++value, increment the value before giving me it.

value ++,给我当前值,并在表达式后面添加一个值,++ value,在给它之前递增值。

Expressions like a ++ + ++ b, are simple to work out if you just remember the above.

如果你只记得上面的内容,像++ ++ ++ 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;
           

I suppose you've just got to remember who has to read through the code, if you have a team that knows JS inside out then you don't need to worry.

我想你必须记住谁必须阅读代码,如果你有一个团队知道JS内部,那么你不必担心。

If not then comment it, write it differently, etc. Do what you got to do.

如果没有,那么评论它,写不同,等等。做你需要做的。

I don't think increment and decrement is inherently bad or bug generating, or vulnerability creating, maybe just less readable depending on your audience.

我不认为增量和减量本质上是坏的或产生错误,或者创建漏洞,可能根据您的受众而言可读性较低。

Btw, I think Douglas Crockford is a legend anyway, but I think he's caused a lot of scare over an operator that didn't deserve it.

顺便说一句,我认为道格拉斯·克罗克福德无论如何都是一个传奇,但我认为他对一个不值得的运营商造成了很大的恐慌。

I live to be proven wrong though...

我活得被证明是错的......

继续阅读