Recientemente descubrí eso 2 == [2]
en JavaScript. Resulta que esta peculiaridad tiene un par de consecuencias interesantes:
var a = [0, 1, 2, 3];
a[[2]] === a[2]; // this is true
Del mismo modo, los siguientes trabajos:
var a = { "abc" : 1 };
a[["abc"]] === a["abc"]; // this is also true
Aún más extraño, esto también funciona:
[[[[[[[2]]]]]]] == 2; // this is true too! WTF?
Estos comportamientos parecen consistentes en todos los navegadores.
¿Alguna idea de por qué esta es una característica del lenguaje?
Aquí hay consecuencias más locas de esta "característica":
[0] == false // true
if ([0]) { /* executes */ } // [0] is both true and false!
var a = [0];
a == a // true
a == !a // also true, WTF?
Estos ejemplos fueron encontrados por jimbojw http://jimbojw.com fama, así como walkingeyerobot .
fuente
+"2"
es también el número 2.En el lado derecho de la ecuación, tenemos a [2], que devuelve un tipo de número con valor 2. A la izquierda, primero estamos creando una nueva matriz con un solo objeto de 2. Luego estamos llamando a [( matriz está aquí)]. No estoy seguro de si esto se evalúa como una cadena o un número. 2 o "2". Tomemos el caso de la cuerda primero. Creo que un ["2"] crearía una nueva variable y devolvería nulo. null! == 2. Entonces supongamos que se está convirtiendo implícitamente en un número. a [2] devolvería 2. 2 y 2 coinciden en tipo (entonces === funciona) y valor. Creo que está convirtiendo implícitamente la matriz en un número porque un [valor] espera una cadena o número. Parece que el número tiene mayor prioridad.
En una nota al margen, me pregunto quién determina esa precedencia. ¿Es porque [2] tiene un número como primer elemento, por lo que se convierte en un número? ¿O es que al pasar una matriz a una [matriz], primero intenta convertir la matriz en un número y luego en una cadena. ¿Quién sabe?
En este ejemplo, está creando un objeto llamado a con un miembro llamado abc. El lado derecho de la ecuación es bastante simple; es equivalente a a.abc. Esto devuelve 1. El lado izquierdo primero crea una matriz literal de ["abc"]. Luego busca una variable en un objeto pasando la matriz recién creada. Como esto espera una cadena, convierte la matriz en una cadena. Esto ahora se evalúa como un ["abc"], que es igual a 1. 1 y 1 son del mismo tipo (razón por la cual === funciona) e igual valor.
Esto es solo una conversión implícita. === no funcionaría en esta situación porque hay un desajuste de tipo.
fuente
==
aplicaToPrimitive()
a la matriz, que a su vez invoca sutoString()
método, por lo que lo que realmente compara es el número2
con la cadena"2"
; La comparación entre una cadena y un número se realiza mediante la conversión de la cadenaPara el
==
caso, esta es la razón por la cual Doug Crockford recomienda usar siempre===
. No realiza ninguna conversión de tipo implícito.Para los ejemplos con
===
, la conversión de tipo implícito se realiza antes de que se llame al operador de igualdad.fuente
Eso es interesante, no es que [0] sea verdadero y falso, en realidad
Es la forma divertida de javascript de procesar el operador if ().
fuente
==
trabajar; si usa un reparto explícito real (es decirBoolean([0])
o!![0]
), usted encontrará que[0]
se evaluará comotrue
en contextos booleanos como debe ser: en JS, se considera cualquier objetotrue
Una matriz de un elemento puede tratarse como el elemento mismo.
Esto se debe a la escritura del pato. Desde "2" == 2 == [2] y posiblemente más.
fuente
==
operador antes de comparar.Para agregar un pequeño detalle a las otras respuestas ... al comparar una
Array
con unaNumber
, Javascript convertirá laArray
conparseFloat(array)
. Puede probarlo usted mismo en la consola (por ejemplo, Firebug o Web Inspector) para ver a qué diferentesArray
valores se convierten.Para
Array
s,parseFloat
realiza la operación en elArray
primer miembro del 's y descarta el resto.Editar: según los detalles de Christoph, puede ser que esté usando la forma más larga internamente, pero los resultados son consistentemente idénticos
parseFloat
, por lo que siempre puede usarparseFloat(array)
como abreviatura para saber con certeza cómo se convertirá.fuente
Estás comparando 2 objetos en cada caso. No uses ==, si estás pensando en una comparación, tienes === en mente y no ==. == a menudo puede dar efectos locos. Busque las partes buenas en el idioma :)
fuente
Explicación de la sección EDITAR de la pregunta:
1er ejemplo
Primero encasillado [0] a un valor primitivo según la respuesta de Christoph anterior tenemos "0" (
[0].valueOf().toString()
)Ahora, escriba Boolean (falso) a Number y luego String ("0") a Number
En cuanto a la
if
declaración, si no hay una comparación explícita en la condición if en sí, la condición se evalúa como verdadera valores de .Solo hay 6 valores falsos: falso, nulo, indefinido, 0, NaN y cadena vacía "". Y cualquier cosa que no sea un valor falso es un valor verdadero.
Como [0] no es un valor falso, es un valor verdadero, la
if
declaración se evalúa como verdadera y ejecuta la declaración.2do ejemplo
De nuevo, escriba fundir los valores a primitivo,
fuente