Eu descobri recentemente isso 2 == [2]
em JavaScript. Acontece que essa peculiaridade tem algumas consequências interessantes:
var a = [0, 1, 2, 3];
a[[2]] === a[2]; // this is true
Da mesma forma, o seguinte funciona:
var a = { "abc" : 1 };
a[["abc"]] === a["abc"]; // this is also true
Ainda mais estranho, isso também funciona:
[[[[[[[2]]]]]]] == 2; // this is true too! WTF?
Esses comportamentos parecem consistentes em todos os navegadores.
Alguma idéia de por que esse é um recurso de idioma?
Aqui estão as consequências mais insanas desse "recurso":
[0] == false // true
if ([0]) { /* executes */ } // [0] is both true and false!
var a = [0];
a == a // true
a == !a // also true, WTF?
Estes exemplos foram encontrados por jimbojw http://jimbojw.com fama bem como walkingeyerobot .
fonte
+"2"
é também o número 2.No lado direito da equação, temos a [2], que retorna um tipo de número com o valor 2. À esquerda, primeiro criamos uma nova matriz com um único objeto de 2. Em seguida, chamamos um [( matriz está aqui)]. Não tenho certeza se isso é avaliado como uma sequência ou um número. 2 ou "2". Vamos pegar o estojo de cordas primeiro. Eu acredito que um ["2"] criaria uma nova variável e retornaria nulo. null! == 2. Então, vamos supor que ele esteja convertendo implicitamente em um número. a [2] retornaria 2. 2 e 2 correspondem ao tipo (então === funciona) e valor. Eu acho que está implicitamente convertendo a matriz em um número porque um [valor] espera uma string ou número. Parece que o número tem maior precedência.
Em uma nota lateral, pergunto-me quem determina essa precedência. É porque [2] tem um número como seu primeiro item, então ele converte em um número? Ou é que, ao passar um array para um [array], ele tenta transformar o array em um número primeiro e depois em uma string. Quem sabe?
Neste exemplo, você está criando um objeto chamado a com um membro chamado abc. O lado direito da equação é bem simples; é equivalente a a.abc. Isso retorna 1. O lado esquerdo primeiro cria uma matriz literal de ["abc"]. Em seguida, você procura uma variável no objeto passando na matriz recém-criada. Como isso espera uma sequência, ele converte a matriz em uma sequência. Isso agora é avaliado como um ["abc"], que é igual a 1. 1 e 1 são do mesmo tipo (e é por isso que === funciona) e igual valor.
Esta é apenas uma conversão implícita. === não funcionaria nessa situação porque há uma incompatibilidade de tipo.
fonte
==
aplicaToPrimitive()
- se à matriz, que por sua vez chama seutoString()
método, então o que você realmente compara é o número2
da string"2"
; comparação entre uma corda e um número é feito convertendo a stringPara o
==
caso, é por isso que Doug Crockford recomenda sempre o uso===
. Não faz nenhuma conversão implícita de tipo.Para os exemplos com
===
, a conversão implícita de tipo é feita antes que o operador de igualdade seja chamado.fonte
Isso é interessante, não é que [0] seja verdadeiro e falso, na verdade
É a maneira engraçada de javascript de processar o operador if ().
fonte
==
funciona; se você usar uma conversão explícita real (ou seja,Boolean([0])
ou!![0]
), você verá que[0]
irá avaliar atrue
em contextos boolean como deveria: em JS, qualquer objeto é consideradotrue
Uma matriz de um item pode ser tratada como o próprio item.
Isto é devido à digitação de pato. Desde "2" == 2 == [2] e possivelmente mais.
fonte
==
operador antes da comparação.Para adicionar um pequeno detalhe às outras respostas ... ao comparar um
Array
para umNumber
, o Javascript converterá oArray
comparseFloat(array)
. Você pode tentar você mesmo no console (por exemplo, Firebug ou Web Inspector) para ver para quaisArray
valores diferentes são convertidos.Para
Array
s,parseFloat
executa a operação noArray
primeiro membro do e descarta o restante.Edit: Pelos detalhes de Christoph, pode ser que ele esteja usando a forma mais longa internamente, mas os resultados são sempre idênticos
parseFloat
, portanto você sempre pode usarparseFloat(array)
como atalho para saber com certeza como será convertido.fonte
Você está comparando 2 objetos em todos os casos. Não use ==, se você estiver pensando em comparação, estará pensando em === e não ==. == muitas vezes pode dar efeitos insanos. Procure as partes boas da linguagem :)
fonte
Explicação para a seção EDIT da pergunta:
1º exemplo
Primeiro, digite [0] para um valor primitivo conforme a resposta de Christoph acima, temos "0" (
[0].valueOf().toString()
)Agora, digite Boolean (false) para Number e, em seguida, String ("0") para Number
Quanto à
if
declaração, se não houver uma comparação explícita na própria condição if, a condição será avaliada quanto à verdade valores de .Existem apenas 6 valores falsos: falso, nulo, indefinido, 0, NaN e sequência vazia "". E qualquer coisa que não seja um valor falso é um valor verdadeiro.
Como [0] não é um valor falso, é um valor
if
verdadeiro , a instrução é avaliada como verdadeira e executa a instrução.2º Exemplo
Novamente, digite a conversão dos valores para primitivo,
fonte