Uma das dicas para a ferramenta jslint é:
++ e -
Sabe-se que os operadores ++ (incremento) e - (decremento) contribuem para códigos incorretos, incentivando truques excessivos. Eles perdem apenas para a arquitetura defeituosa na ativação de vírus e outras ameaças à segurança. Existe uma opção plusplus que proíbe o uso desses operadores.
Eu sei que construções PHP como $foo[$bar++]
has podem facilmente resultar em erros de um por um, mas não consegui descobrir uma maneira melhor de controlar o loop do que um while( a < 10 ) do { /* foo */ a++; }
ou for (var i=0; i<10; i++) { /* foo */ }
.
O jslint está destacando-os porque existem algumas linguagens semelhantes que não possuem a sintaxe " ++
" e " --
" ou a tratam de maneira diferente, ou existem outras razões para evitar " ++
" e " --
" que eu possa estar perdendo?
++
não causa bugs. O uso de++
maneiras "complicadas" pode levar a erros, especialmente se mais de uma pessoa estiver mantendo a base de código, mas isso não é um problema do operador, é um problema do programador. Eu não aprendi JS na universidade (porque ainda não existia), mas e daí? Eu fiz C, que é claro que tinha++
primeiro, mas que também recebe um "e daí?" Não fui à universidade para aprender um idioma específico, fui aprender boas práticas de programação que posso aplicar a qualquer idioma.Respostas:
Minha opinião é sempre usar ++ e - sozinhos em uma única linha, como em:
ao invés de
Qualquer coisa além disso pode ser confusa para alguns programadores e simplesmente não vale a pena, na minha opinião. Os loops são uma exceção, pois o uso do operador de incremento é idiomático e, portanto, sempre claro.
fonte
i
variável se torne uma classe composta posteriormente; nesse caso, você criaria desnecessariamente um objeto temporário. Acho o operador postfix mais esteticamente agradável.Estou francamente confuso com esse conselho. Parte de mim se pergunta se isso tem mais a ver com a falta de experiência (percebida ou real) com codificadores javascript.
Eu posso ver como alguém que está "hackeando" algum código de exemplo pode cometer um erro inocente com ++ e -, mas não vejo por que um profissional experiente os evitaria.
fonte
++
expressão é mais complicada, na qual ++ x é diferente de x ++, resultando em algo que não é fácil de ler. A ideia de Crockford não é sobre 'posso fazer isso?' é sobre 'como posso evitar erros?'Há uma história em C de fazer coisas como:
para copiar uma string, talvez essa seja a fonte do truque excessivo a que ele está se referindo.
E sempre há a questão do que
ou
realmente fazer. É definido em alguns idiomas e em outros não há garantia do que acontecerá.
Esses exemplos à parte, acho que não há nada mais idiomático do que um loop for que usa
++
para incrementar. Em alguns casos, você pode se dar bem com um loop foreach ou um loop while que verifica uma condição diferente. Mas contorcer seu código para tentar evitar o incremento é ridículo.fonte
x = a+++b
->x = (a++)+b
->x = a + b; a++
. O tokeniser é ganancioso.Se você ler JavaScript The Good Parts, você verá que o substituto de Crockford para i ++ em um por ciclo é i + = 1 (não i = i + 1). Isso é bastante limpo e legível, e é menos provável que se transforme em algo "complicado".
Crockford fez da proibição do incremento automático e do autodecremento uma opção no jsLint. Você escolhe se segue o conselho ou não.
Minha regra pessoal é não fazer nada combinado com incremento automático ou autodecremento.
Aprendi com anos de experiência em C que não recebo saturações de buffer (ou índice de matriz fora dos limites) se eu continuar usando-o de maneira simples. Mas descobri que recebo excedentes de buffer se cair na prática "excessivamente complicada" de fazer outras coisas na mesma declaração.
Assim, por minhas próprias regras, o uso de i ++ como o incremento de uma para circuito é bom.
fonte
Em um loop, é inofensivo, mas em uma declaração de atribuição pode levar a resultados inesperados:
O espaço em branco entre a variável e o operador também pode levar a resultados inesperados:
Em um fechamento, resultados inesperados também podem ser um problema:
E aciona a inserção automática de ponto e vírgula após uma nova linha:
Referências
fonte
==
porque você não entende a diferença entre==
e===
.a: 2 b: 0 c: 1
. Também não vejo nada de estranho ou inesperado no primeiro exemplo ("declaração de atribuição").Considere o seguinte código
desde que o i ++ é avaliado duas vezes a saída é (do depurador vs2005)
Agora considere o seguinte código:
Observe que a saída é a mesma. Agora você pode pensar que ++ ie i ++ são iguais. Eles não são
Por fim, considere este código
A saída é agora:
Portanto, eles não são os mesmos; misturar os dois resulta em um comportamento não tão intuitivo. Eu acho que para loops estão ok com ++, mas cuidado quando você tem vários símbolos ++ na mesma linha ou na mesma instrução
fonte
A natureza "pré" e "pós" dos operadores de incremento e decremento pode tender a ser confusa para aqueles que não estão familiarizados com eles; essa é uma maneira pela qual eles podem ser complicados.
fonte
Na minha opinião, "explícito é sempre melhor do que implícito". Porque em algum momento, você pode ficar confuso com essa instrução de incrementos
y+ = x++ + ++y
. Um bom programador sempre torna seu código mais legível.fonte
A justificativa mais importante para evitar ++ ou - é que os operadores retornem valores e causem efeitos colaterais ao mesmo tempo, dificultando o raciocínio sobre o código.
Por uma questão de eficiência, prefiro:
Sou fã do Sr. Crockford, mas neste caso tenho que discordar.
++i
é 25% menos texto para analisar do quei+=1
e sem dúvida mais claro.fonte
Estive assistindo o vídeo de Douglas Crockford sobre isso e sua explicação para não usar incremento e decremento é que
Em primeiro lugar, as matrizes em JavaScript são dinamicamente dimensionadas e, portanto, desculpe-me se estiver errado, não é possível quebrar os limites de uma matriz e acessar dados que não devem ser acessados usando esse método em JavaScript.
Em segundo lugar, devemos evitar coisas complicadas, certamente o problema não é que temos esse recurso, mas o problema é que existem desenvolvedores por aí que afirmam fazer JavaScript, mas não sabem como esses operadores funcionam? É bastante simples. value ++, me dê o valor atual e, após a expressão, adicione um, ++ value, aumente o valor antes de me fornecer.
Expressões como a ++ + ++ b, são simples de resolver, se você se lembrar do que foi dito acima.
Suponho que você apenas se lembre de quem precisa ler o código. Se você tem uma equipe que conhece JS de dentro para fora, não precisa se preocupar. Caso contrário, comente-o, escreva-o de forma diferente, etc. Faça o que você deve fazer. Não acho que incremento e decremento sejam inerentemente ruins ou gerem bugs ou criem vulnerabilidades, talvez apenas menos legíveis, dependendo do seu público.
Aliás, acho que Douglas Crockford é uma lenda de qualquer maneira, mas acho que ele causou muito susto em um operador que não o merecia.
Eu vivo para ser provado errado embora ...
fonte
Outro exemplo, mais simples que outros com retorno simples de valor incrementado:
Como você pode ver, nenhum pós-incremento / decremento deve ser usado na declaração de retorno, se você desejar que este operador influencie o resultado. Mas o retorno não "captura" os operadores pós-incremento / decremento:
fonte
Eu acho que os programadores devem ser competentes no idioma que estão usando; use-o claramente; e use-o bem. Eu não acho que eles devam aleijar artificialmente o idioma que estão usando. Eu falo por experiência própria. Certa vez, eu trabalhei literalmente ao lado de uma loja Cobol onde eles não usavam o ELSE 'porque era muito complicado'. Reductio ad absurdam.
fonte
Como mencionado em algumas das respostas existentes (que irritantemente não consigo comentar), o problema é que x ++ ++ x é avaliado com valores diferentes (antes vs após o incremento), o que não é óbvio e pode ser muito confuso - se esse valor for usado. O cdmckay sugere com muita sabedoria permitir o uso do operador de incremento, mas apenas de uma maneira que o valor retornado não seja usado, por exemplo, em sua própria linha. Também incluiria o uso padrão em um loop for (mas apenas na terceira instrução, cujo valor de retorno não é usado). Não consigo pensar em outro exemplo. Tendo sido "queimado", eu recomendaria a mesma diretriz para outros idiomas também.
Não concordo com a afirmação de que esse excesso de rigidez deve-se ao fato de muitos programadores de JS serem inexperientes. Esse é o tipo exato de escrita típico de programadores "excessivamente inteligentes", e tenho certeza de que é muito mais comum em linguagens mais tradicionais e com desenvolvedores de JS que têm experiência em tais linguagens.
fonte
Na minha experiência, ++ i ou i ++ nunca causou confusão, a não ser quando aprendemos pela primeira vez sobre como o operador funciona. É essencial para os mais básicos loops e loops ministrados por qualquer curso de ensino médio ou superior, ministrado em idiomas nos quais você pode usar o operador. Pessoalmente, acho que fazer algo como o que está abaixo para parecer e ler melhor do que algo com um ++ estando em uma linha separada.
No final, é uma preferência de estilo e nada mais, o mais importante é que, quando você faz isso em seu código, permanece consistente para que outras pessoas que trabalham no mesmo código possam seguir e não precisar processar a mesma funcionalidade de maneiras diferentes. .
Além disso, Crockford parece usar i- = 1, que acho mais difícil de ler do que --i ou i--
fonte
Meu 2 centavos é que eles devem ser evitados em dois casos:
1) Quando você tem uma variável usada em várias linhas e a aumenta / diminui na primeira instrução que a usa (ou por último, ou, pior ainda, no meio):
Em exemplos como esse, você pode facilmente esquecer que a variável é incrementada / decrementada automaticamente ou até remover a primeira instrução. Em outras palavras, use-o apenas em blocos muito curtos ou em que a variável apareça no bloco em apenas algumas instruções próximas.
2) No caso de múltiplos ++ e - sobre a mesma variável na mesma instrução. É muito difícil lembrar o que acontece em casos como este:
Exames e testes profissionais perguntam sobre exemplos como acima e, de fato, eu me deparei com essa pergunta enquanto procurava documentação sobre um deles, mas na vida real não devemos ser forçados a pensar tanto em uma única linha de código.
fonte
O Fortran é um idioma semelhante ao C? Não possui nem ++ nem -. Aqui está como você escreve um loop :
O elemento de índice i é incrementado pelas regras de linguagem todas as vezes no loop. Se você deseja incrementar algo diferente de 1, conte duas vezes para trás, por exemplo, a sintaxe é ...
O Python é do tipo C? Ele usa compreensões de intervalo e lista e outras sintaxes para ignorar a necessidade de incrementar um índice:
Portanto, com base nessa exploração rudimentar de exatamente duas alternativas, os designers de linguagem podem evitar ++ e - antecipando casos de uso e fornecendo uma sintaxe alternativa.
Fortran e Python são notavelmente menos atraentes de erros do que linguagens procedurais que possuem ++ e -? Eu não tenho provas.
Afirmo que Fortran e Python são do tipo C porque nunca conheci alguém fluente em C que não pudesse, com precisão de 90%, adivinhar corretamente a intenção do Fortran ou do Python não ofuscados.
fonte