Зачем избегать операций увеличения ("++") и уменьшения ("-") в JavaScript? - PullRequest
343 голосов
/ 09 июня 2009

Один из советов для инструмента jslint :

++ и -
++ (увеличение) и - (уменьшение) Операторы, как известно, способствуют плохому коду поощряя чрезмерную хитрость. Oни уступают только неисправной архитектуре в активации вирусов и других угрозы безопасности. Есть плюс вариант, который запрещает использование этих операторы.

Я знаю, что PHP-конструкции, подобные $foo[$bar++], могут легко привести к ошибкам, не связанным с одной, но я не мог найти лучший способ управления циклом, чем while( a < 10 ) do { /* foo */ a++; } или for (var i=0; i<10; i++) { /* foo */ }.

Подсвечивает ли jslint их, потому что есть некоторые похожие языки, в которых нет синтаксиса "++" и "--", или они обрабатываются по-разному, или есть другие причины для избежания "++" и "-- "что я могу пропустить?

Ответы [ 17 ]

10 голосов
/ 18 сентября 2013

Другой пример, более простой, чем некоторые другие, с простым возвратом инкрементного значения:

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
}
8 голосов
/ 27 сентября 2010

Я думаю, что программисты должны быть компетентны в языке, который они используют; используйте это ясно; и используйте это хорошо. Я не думаю, что они должны искусственно исказить язык, который они используют. Я говорю из опыта. Однажды я работал буквально по соседству с магазином Cobol, где они не использовали ELSE «потому что это было слишком сложно». Reductio ad absurdam.

2 голосов
/ 30 сентября 2016

Мои 2цента - это то, что их следует избегать в двух случаях:

1) Если у вас есть переменная, которая используется во многих строках, и вы увеличиваете / уменьшаете ее в первом операторе, который ее использует (или последний, или, что еще хуже, в середине):

// It's Java, but applies to Js too
vi = list.get ( ++i );
vi1 = list.get ( i + 1 )
out.println ( "Processing values: " + vi + ", " + vi1 )
if ( i < list.size () - 1 ) ...

В подобных примерах вы можете легко пропустить, что переменная автоматически увеличивается / уменьшается, или даже удалить первый оператор. Другими словами, используйте его только в очень коротких блоках или там, где переменная появляется в блоке только на паре операторов close.

2) В случае нескольких ++ и - примерно одной и той же переменной в одном выражении. Очень трудно вспомнить, что происходит в таких случаях:

result = ( ++x - --x ) * x++;

Экзамены и профессиональные тесты запрашивают примеры, подобные приведенным выше, и я действительно наткнулся на этот вопрос, когда искал документацию по одному из них, но в реальной жизни не следует заставлять так много думать об одной строке кода. .

2 голосов
/ 22 июня 2016

По моему опыту, ++ i или i ++ никогда не вызывали путаницы, кроме как при первом знакомстве с работой оператора. Это важно для самых базовых циклов и циклов while, которые преподаются в любой школе или колледже на языках, где вы можете использовать оператор. Лично я нахожу что-то вроде того, что ниже, чтобы выглядеть и читать лучше, чем что-то, а ++ стоит на отдельной строке.

while ( a < 10 ){
    array[a++] = val
}

В конце концов, это предпочтение стиля, а не что-то более, что более важно, что когда вы делаете это в своем коде, вы остаетесь последовательными, так что другие, работающие над тем же кодом, могут следовать и не должны обрабатывать одну и ту же функциональность по-разному.

Кроме того, Крокфорд, похоже, использует i- = 1, что, на мой взгляд, труднее читать, чем --i или i -

2 голосов
/ 06 августа 2009

Не знаю, было ли это частью его рассуждений, но если вы используете плохо написанную программу минификации, она может превратить x++ + y в x+++y. Но опять же, плохо написанный инструмент может нанести всевозможные разрушения.

2 голосов
/ 27 января 2011

Как уже упоминалось в некоторых существующих ответах (что досадно, я не могу комментировать), проблема заключается в том, что x ++ ++ x оценивает различные значения (до и после увеличения), что неочевидно и очень запутанно - , если это значение используется. cdmckay предлагает весьма разумно разрешить использование оператора приращения, но только таким образом, чтобы возвращаемое значение не использовалось, например, на своей собственной линии. Я бы также включил стандартное использование в цикл for (но только в третьем операторе, возвращаемое значение которого не используется). Я не могу придумать другой пример. Будучи сам "сожженным", я бы порекомендовал эту же рекомендацию и для других языков.

Я не согласен с утверждением, что эта чрезмерная строгость вызвана неопытностью многих программистов JS. Это именно тот тип письма, который типичен для «чрезмерно умных» программистов, и я уверен, что он гораздо чаще встречается на более традиционных языках и у разработчиков JS, имеющих опыт работы с такими языками.

1 голос
/ 09 июня 2009

Является ли Фортран С-подобным языком? У него нет ни ++, ни -. Вот как как вы пишете цикл :

     integer i, n, sum

      sum = 0
      do 10 i = 1, n
         sum = sum + i
         write(*,*) 'i =', i
         write(*,*) 'sum =', sum
  10  continue

Элемент индекса i увеличивается по правилам языка каждый раз в цикле. Если вы хотите увеличить на что-то, отличное от 1, например, сосчитать назад на два, синтаксис ...

      integer i

      do 20 i = 10, 1, -2
         write(*,*) 'i =', i
  20  continue

Является ли Python C-подобным? Он использует диапазон и списки и другие синтаксисы, чтобы обойти необходимость увеличения индекса:

print range(10,1,-2) # prints [10,8.6.4.2]
[x*x for x in range(1,10)] # returns [1,4,9,16 ... ]

Таким образом, основываясь на этом элементарном исследовании ровно двух альтернатив, разработчики языка могут избежать ++ и - предвидя варианты использования и предоставляя альтернативный синтаксис.

Являются ли Fortran и Python меньшей ошибкой, чем процедурные языки с ++ и -? У меня нет доказательств.

Я утверждаю, что Fortran и Python подобны C, потому что я никогда не встречал человека, свободно говорящего на C, который не мог бы с 90% -ной точностью угадать намерение не скрытого Fortran или Python.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...