天天看點

為什麼要避免使用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...

我活得被證明是錯的......

繼續閱讀