Jshint: Opt-out de `Uso confuso de '!'.`

Criado em 13 fev. 2012  ·  41Comentários  ·  Fonte: jshint/jshint

Esta verificação foi adicionada para o problema # 211, mas não há como cancelar essa detecção. Conforme sugerido pelo autor da postagem original do problema, ele deve ser ativado por padrão, mas com uma substituição.

Comentários muito úteis

!! é a maneira mais fácil de converter "qualquer coisa" em "bool". +1 para opt-out

Todos 41 comentários

Você poderia nos dar um exemplo de uso válido, por favor?

https://github.com/jshint/jshint/issues/211#issuecomment -3942380

Também estou curioso sobre a detecção do IE6.

Fechando este tíquete, pois não obtivemos nenhum exemplo de uso válido. Sinta-se à vontade para reabri-lo mais tarde.

É

if( !!a === !!b ){  

uma amostra válida (operandos typecast para bool)?
Eu acho isso mais conciso do que

if( (a && b) || (!a && !b) ) {

Sim, isso é bom.

Os exemplos do número 211 ainda são válidos, ou seja, 'confusos' ou mesmo perigosos.
Não tenho certeza se opt-out é a melhor solução ou se `!! x 'deve ser considerado válido?

if (! (mseq <= this.messages.length)) {lançar novo erro ('mseq inválido:' + mseq); }

Este irá gerar um erro quando mseq não for um número tão bem se for maior que this.messages.length

Vim aqui com um caso de uso semelhante a @axkibe. O caso invertido não detectará erros de intervalo e de dados inválidos de uma vez.

Isso não me parece uma prática ruim, considerando que o código resultante é legível e direto em sua intenção.

O recurso matador do jshint é o opt-out, em oposição ao crockford-ed-in.

Para maior clareza, em nosso teste de unidade, assert.greater et al definido como tal:

        greater: function(lhs, rhs) {
            if (!(lhs > rhs)) {
                fail(new AssertionError(repr(lhs) + ' not greater than ' + repr(rhs)));
            }
        },

        less: function(lhs, rhs) {
            if (!(lhs < rhs)) {
                fail(new AssertionError(repr(lhs) + ' not less than ' + repr(rhs)));
            }
        },

        greaterOrEqual: function(lhs, rhs) {
            if (!(lhs >= rhs)) {
                fail(new AssertionError(repr(lhs) + ' not greater than or equal to ' + repr(rhs)));
            }
        },

        lessOrEqual: function(lhs, rhs) {
            if (!(lhs <= rhs)) {
                fail(new AssertionError(repr(lhs) + ' not less than or equal to ' + repr(rhs)));
            }
        },

Escrevi dessa forma para maior clareza e agradeceria uma desativação para este aviso.

+1 de minha parte por uma exclusão (fomos pegos em !!a == !!b ).

BTW, parece ser uma duplicata: https://github.com/jshint/jshint/issues/578

Isso é um erro, não um aviso. Pelos comentários de documentos do commit de fechamento , os avisos podem ser ignorados, mas não os erros.

Então, o que devo fazer em vez de if (! (Event.which == ESCAPE_KEY)) {de acordo com suas melhores práticas?

Por que você escreveria isso?

O que há de errado em ser claro sobre a intenção do programa?

if (event.which !== ESCAPE_KEY) {...}

Não é meu código, não sei as intenções. Eu encontrei em alguma lib e o jshint não estava validando por causa disso.

Por que você está editando código de biblioteca de terceiros? Não é esse o trabalho do autor?

Seja ou não! (A == b) é feio ou não, deveria haver um opt-out, certo? Achei que a filosofia do jshint era fornecer um opt-out para todos os avisos.

Pessoalmente, no caso de asserções de framework de teste, achei mais claro escrever a condicional para corresponder à asserção:

function assertEqual(x, y) {
    if (!(x == y)) { ... }

function assertNotEqual(x, y) {
    if (!(x != y)) { ... }

function assertGreater(x, y) {
    if (!(x > y)) { ... }

Que tal este exemplo?

if ( !((end - start) % 2) ) // do stuff

Eu poderia criar uma variável para manter esse valor, mas por quê? Para mim, isso não parece um uso confuso do operador NOT, então não deve gerar um erro.

Por que você precisa ser "inteligente" aqui? O que há de errado em apenas escrever o que você realmente quer dizer? (a - b) % 2 === 0

Se alguém quiser escrever I patch, terei o prazer de revisá-lo para inclusão, mas até então não quero ler outro comentário neste tópico. Menos conversa, mais ação. Podemos discutir qualquer patch que vier, tanto quanto o autor ou contribuidores e as partes interessadas quiserem.

Eu tenho um caso de uso. Estou recuperando um valor de um banco de dados que deveria ser booleano, mas retorna como '0' ou '1' . Estou fazendo a conversão com !!+val , que se converte em número e depois em booleano, mas produz este aviso jshint. Adicionar parênteses não silencia o aviso. Nenhum aviso ocorre com !!val mas isso não é correto porque '0' ao contrário de 0 é verdadeiro. Acabei desabilitando W018 para a linha em questão.

+1 para cancelamento, !!x é um caso de uso válido e um idioma comum para converter para bool como @mgoldWork e @ jakub-g apontaram

+1 para !!a === !!b

na verdade, !!x pode ser usado em qualquer lugar para converter para bool ...

poderia ser marcado como construção válida em jshint (sem necessidade de opt-out), @valueof?

+1 para cancelar

É ótimo quando o primeiro resultado do Google para um problema é um assunto fechado sem solução.

De acordo com o # 780, esta opção pode ser desabilitada / habilitada com o não-enigmático /*jshint -W018 */ e /*jshint +W018 */

1 para um opt-out mais enigmático.

@ cjc343 obrigado.

deve haver uma maneira de cancelar .jshintrc também.

sempre que alguém pede uma maneira de cancelar algo, as pessoas sempre respondem "mas por que você iria querer escrever isso, que código ruim é ruim". esta nunca é uma resposta válida a alguém que pede um opt-out. se eles estão pedindo um opt-out, eles discordam de você que é 100% sempre ruim, e é isso. jshint deve nos ajudar, não atrapalhar. tudo deve ser desativado. absolutamente tudo.

O que é o campo .jshintrc para permitir o uso confuso de ! ?

Por exemplo, o seguinte está me dando o aviso:

function even(n) {
  return !(n % 2)
}

+1 para cancelar

Você poderia nos dar um exemplo de uso válido, por favor?

console.assert(!!prototype === !!object, 'invalid state', prototype, object);

+1. Aqui está um dos meus casos de uso comuns:

// Note: points is an array, each having latitude and longitude
var dataset = {};
points.forEach(function(point){
    if (!(dataset.latMin<point.lat)) dataset.latMin = point.lat;
});

Observe que !(dataset.latMin<point.lat) não é o mesmo que dataset.latMin>=point.lat quando o LHS é indefinido.

Observe que! (Dataset.latMin= point.lat quando o LHS é indefinido.

Isso não é confuso para a pessoa pobre que lê o código?

De qualquer forma, isso foi mesclado com o # 780, onde é observado que você pode usar W018 para desativar este aviso.

if (data === undefined || (!(data.length > 0))) 

é considerado confuso. então é

if (data === undefined || !(data.length > 0)) 

O que fazer?

Você tentou

-if (data === undefined || !(data.length > 0)) 
+if (data === undefined || data.length <= 0) 

... embora um nome de propriedade como length me faça suspeitar que data.length === 0 pode ser suficiente.

Não é equivalente, porque para um objeto não array sem propriedade de comprimento, seus exemplos fornecem falso.
Agora eu percebo que também há strings com a propriedade padrão "length", então posso ter que verificar o tipo primeiro, também -.-

Whether or not ** is ugly or not, there should be an opt-out, right?

sim. Não sei por que isso está sendo discutido.

!! é a maneira mais fácil de converter "qualquer coisa" em "bool". +1 para opt-out

O caso que continuo encontrando é de querer testar se algo não é um número positivo:
if (!(n > 0))
Caso contrário, é necessário escrever algo como:
if (typeof n != 'number' || isNaN(n) || n <= 0)

O caso que continuo encontrando é de querer testar se algo não é um número positivo:
if (! (n> 0))
Caso contrário, é necessário escrever algo como:
if (typeof n! = 'número' || isNaN (n) || n <= 0)

É exatamente por isso que vim aqui me perguntando por que o jshint estava me impedindo de escrever código da maneira que desejo.

!(n > 0) e typeof n != 'number' || isNaN(n) || n <= 0 não são a mesma coisa:

var n = "1";
console.log(!(n > 0)); // false
console.log(typeof n != 'number' || isNaN(n) || n <= 0) // true

De qualquer forma, você pode apenas usar -W018 para desativar o aviso

Esta página foi útil?
0 / 5 - 0 avaliações