validar validacion tablas sirve que para formularios formulario enviar ejemplos con codigo antes javascript

javascript - validacion - Las matrices vacías parecen ser verdaderas y falsas al mismo tiempo



validar formulario javascript html5 (6)

Ejemplo:

const array = [] const boolValueOfArray = !!array // true

Sucede porque

ToNumber(ToPrimitive([])) == ToNumber(false)

  1. [] está vacío Array object → ToPrimitive([]) → "" → ToNumber("")0
  2. ToNumber(false) → 0
  3. 0 == 0 → verdadero

Las matrices vacías son verdaderas pero también son falsas.

var arr = []; console.log(''Array:'', arr); if (arr) console.log("It''s true!"); if (arr == false) console.log("It''s false!"); if (arr && arr == false) console.log("...what??");

Supongo que esto se debe a la conversión implícita operada por el operador de igualdad.

¿Alguien puede explicar lo que sucede detrás de escena?


En cuanto a la línea:

if (arr == false) console.log("It''s false!");

Tal vez esto ayude:

console.log(0 == false) // true console.log([] == 0) // true console.log([] == "") // true

Lo que creo que está sucediendo es que la false booleana se fuerza a 0 para la comparación con un objeto (el lado izquierdo). El objeto es forzado a una cadena (la cadena vacía). Luego, la cadena vacía también se fuerza en un número, es decir, cero. Y entonces la comparación final es 0 == 0 , que es true .

Editar: Consulte esta sección de la especificación para obtener detalles sobre cómo funciona esto exactamente.

Esto es lo que está sucediendo, comenzando en la regla n. ° 1:

1. Si Tipo (x) es diferente de Tipo (y), vaya al paso 14.

La siguiente regla que aplica es # 19:

19. Si Type (y) es booleano, devuelva el resultado de la comparación x == ToNumber (y).

El resultado de ToNumber(false) es 0 , por lo que ahora tenemos:

[] == 0

Nuevamente, la regla n. ° 1 nos dice que saltemos al paso n. ° 14, pero el siguiente paso que realmente aplica es n. ° 21:

21. Si Type (x) es Object y Type (y) es String o Number, devuelve el resultado de la comparación ToPrimitive (x) == y.

El resultado de ToPrimitive([]) es la cadena vacía, por lo que ahora tenemos:

"" == 0

De nuevo, la regla n. ° 1 nos dice que saltemos al paso n. ° 14, pero el siguiente paso que realmente aplica es n. ° 17:

17. Si Type (x) es String y Type (y) es Number, devuelve el resultado de la comparación ToNumber (x) == y.

El resultado de ToNumber("") es 0 , lo que nos deja con:

0 == 0

Ahora, ambos valores tienen el mismo tipo, por lo que los pasos continúan desde el # 1 hasta el # 7, que dice:

7. Si x es el mismo valor numérico que y, devuelve verdadero.

Entonces, volvemos true .

En breve:

ToNumber(ToPrimitive([])) == ToNumber(false)


En if (arr), siempre se evalúa (ToBoolean) en true si arr es un objeto porque todos los objetos en JavaScript son verdaderos . (¡nulo no es un objeto!)

[] == false se evalúa en un enfoque iterativo. Al principio, si un lado de == es primitivo y el otro es objeto, convierte el objeto en primitivo al principio, luego convierte ambos lados en Número si ambos lados no son string (la comparación de cadenas se usa si ambos lados son cadenas). Entonces la comparación se itera como, [] == false -> '''' == false -> 0 == 0 -> true .


Estás probando cosas diferentes aquí.

if (arr) el objeto invocado if (arr) (Array es instancia de Object en JS) verificará si el objeto está presente y devolverá verdadero / falso.

Cuando llama if (arr == false) compara valores de este objeto y el valor false primitivo. Internamente, se llama a arr.toString() , que devuelve una cadena vacía "" .

Esto se debe a que toString Array.join() Array y devuelve Array.join() , y la cadena vacía es uno de los valores falsy en JavaScript.


Ninguno de los anteriores me ayudó cuando trato de usar el complemento de mapeo knockout.js, tal vez porque una "matriz vacía" no está realmente vacía.

Terminé usando: data-bind="if: arr().length" que hizo el truco.

Esto es específico para el knockout, no la pregunta del OP, pero quizás ayude a alguien más a navegar aquí en una situación similar.


Para complementar Wayne''s respuesta Wayne''s y tratar de explicar por qué ToPrimitive([]) devuelve "" , vale la pena considerar dos posibles tipos de respuestas a la pregunta ''por qué''. El primer tipo de respuesta es: "porque la especificación dice que así es como se comportará JavaScript". En la especificación de ES5, sección 9.1 , que describe el resultado de ToPrimitive como valor predeterminado para un objeto:

El valor predeterminado de un objeto se recupera llamando al método interno [[DefaultValue]] del objeto, pasando la sugerencia opcional PreferredType.

La Sección 8.12.8 describe el método [[DefaultValue]] . Este método toma una "pista" como argumento, y la sugerencia puede ser Cadena o Número. Para simplificar el asunto prescindiendo de algunos detalles, si la sugerencia es Cadena, entonces [[DefaultValue]] devuelve el valor de toString() si existe y devuelve un valor primitivo y de lo contrario devuelve el valor de valueOf() . Si la sugerencia es Number, las prioridades de toString() y valueOf() se invierten para que valueOf() se llame primero y se devuelva su valor si se trata de una primitiva. Por lo tanto, si [[DefaultValue]] devuelve el resultado de toString() o valueOf() depende del tipo preferido de PreferredType para el objeto y si estas funciones devuelven valores primitivos.

El método del valor valueOf() predeterminado solo devuelve el objeto en sí, lo que significa que a menos que una clase anule el método predeterminado, valueOf() simplemente devuelve el Object en sí. Este es el caso de Array . [].valueOf() devuelve el objeto [] mismo. Como un objeto Array no es primitivo, la [[DefaultValue]] es irrelevante: el valor de retorno para una matriz será el valor de toString() .

Para citar el JavaScript de David Flanagan : The Definitive Guide , que, por cierto, es un excelente libro que debería ser el primer lugar de todos para obtener respuestas a este tipo de preguntas:

Los detalles de esta conversión de objeto a número explican por qué un conjunto vacío se convierte al número 0 y por qué un conjunto con un elemento individual también puede convertirse en un número. Las matrices heredan el método valueOf () predeterminado que devuelve un objeto en lugar de un valor primitivo, por lo que la conversión de matriz a número se basa en el método toString (). Las matrices vacías se convierten en la cadena vacía. Y la cadena vacía se convierte en el número 0. Una matriz con un solo elemento se convierte en la misma cadena que ese elemento. Si una matriz contiene un solo número, ese número se convierte en una cadena y luego regresa a un número.

El segundo tipo de respuesta a la pregunta "por qué", aparte de "porque dice la especificación", brinda una explicación de por qué el comportamiento tiene sentido desde la perspectiva del diseño. En este tema, solo puedo especular. Primero, ¿cómo se podría convertir una matriz a un número? La única posibilidad sensata que puedo pensar sería convertir una matriz vacía en 0 y cualquier matriz no vacía en 1. Pero como se reveló la respuesta de Wayne, una matriz vacía se convertirá a 0 para muchos tipos de comparaciones de todos modos. Más allá de esto, es difícil pensar en un valor de retorno primitivo sensible para Array.valueOf (). Por lo tanto, podría argumentarse que tiene más sentido tener Array.valueOf() como el valor predeterminado y devolver la matriz en sí, lo que lleva toString() a ser el resultado utilizado por ToPrimitive. Simplemente tiene más sentido convertir una matriz en una cadena, en lugar de un número.

Además, como lo sugiere la cita de Flanagan, esta decisión de diseño permite ciertos tipos de comportamientos beneficiosos. Por ejemplo:

var a = [17], b = 17, c=1; console.log(a==b); // <= true console.log(a==c); // <= false

Este comportamiento le permite comparar una matriz de un solo elemento con números y obtener el resultado esperado.