2010-09-17 12 views
77

Recientemente estaba ejecutando parte de mi código a través de JSLint cuando se me ocurrió este error. Lo que creo que es gracioso acerca de este error es que automáticamente asume que todo == debería ser ===.JSLint Se esperaba '===' y en su lugar vi '=='

¿Eso realmente tiene sentido? Pude ver muchas instancias en las que no querría comparar el tipo y me preocupa que esto realmente pueda causar problemas.

La palabra "Esperado" implicaría que esto debería hacerse CADA vez ... Eso es lo que no tiene sentido para mí.

+6

me encontré con esto también con JSLint. Hice una actualización de == a === y realmente rompió el código que funcionaba anteriormente. – kemiller2002

+4

Si su código tiene más de 100 líneas, no pasará jslint, realmente, es imposible. –

+3

"Rompió" es una palabra demasiado fuerte. Cambió el significado de tu código. Si estaba haciendo una comprobación 'myVar == null', sí, grandes cambios. ; ^) El argumento de Crockford es que hizo que el significado del código sea más preciso, y eso es difícil de discutir. – ruffin

Respuesta

107

OMI, a ciegas utilizando ===, sin tratar de entender cómo tipo de conversión obras no tiene mucho sentido.

El principal temor sobre el operador de igualdad == es que las reglas de comparación en función de los tipos comparados puede hacer que el operador no transitiva, por ejemplo, si:

A == B AND 
B == C 

en realidad no garantiza que :

A == C 

Por ejemplo:

'0' == 0; // true 
0 == ''; // true 
'0' == ''; // false 

El estricto operador de igualdad === no es realmente necesario cuando se comparan los valores del mismo tipo, el ejemplo más común:

if (typeof foo == "function") { 
    //.. 
} 

Se compara el resultado del operador typeof, que es siempre una cadena, con una cadena literal ...

o cuando conoce las reglas de conversión de tipo, por ejemplo, comprobar si algo es algo null o undefined:

if (foo == null) { 
    // foo is null or undefined 
} 

// Vs. the following non-sense version: 

if (foo === null || typeof foo === "undefined") { 
    // foo is null or undefined 
} 
+3

+1, respuesta bien ilustrada – Jakob

+0

@Jakob: ¡Gracias! – CMS

+0

[JSHint] (http://www.jshint.com) - que es como una versión extendida de jslint - tiene una opción para no advertirte sobre "aproximadamente == nulo" verificaciones en particular. –

2

Bueno, realmente no puede causar problemas, solo es aconsejable. Tómelo o déjelo. Dicho esto, no estoy seguro de lo inteligente que es. Puede haber contextos en los que no lo presente como un problema.

+0

, pero ¿por qué se usa la palabra "Esperado"? Eso lo hace parecer que siempre debes hacer esto. – Metropolis

+4

El evaluador está buscando una respuesta válida, ya que está tratando de validarla. Si no obtiene una respuesta válida, entonces no es lo que esperaba. El validador comienza con la suposición de que todo está bien y luego señala los errores a medida que atraviesa el código. No necesariamente entiende qué es una respuesta inválida, solo sabe cuándo ve una no válida. También podría funcionar al revés, buscando deliberadamente código incorrecto según las reglas de lo que es malo. Lista blanca contra lista negra. – Rushyo

+0

La pregunta era "¿Eso realmente tiene sentido?". Ante esa pregunta, sí, lo hace. Además, fue * hace cinco años *. Jesús. – Rushyo

14

Tenga en cuenta que JSLint impone la idea de una sola persona de lo que debería ser el buen JavaScript. Aún debe usar el sentido común al implementar los cambios que sugiere.

En general, comparar el tipo y el valor hará que su código sea más seguro (no se encontrará con el comportamiento inesperado cuando la conversión de tipo no hace lo que cree que debería).

+4

Además, no puede ser tan inteligente según el contexto como un programador. Simplemente funciona sobre la base de que la mayoría de los usuarios se tropiezan con la conversión de tipo automático inherente al sistema (como la violencia, "¡ayúdenme a que me repriman!") – Rudu

7

Una cita de http://javascript.crockford.com/code.html:

=== == y Operadores!.

Casi siempre es mejor usar los operadores === y! ==. Los operadores == y! = Escriben coerción. En en particular, no use == para comparar con los valores de falsy.

JSLint es muy estricto, su 'webjslint.js' ni siquiera pasa su propia validación.

+0

Buena aclaración. Eso es cierto, sobre 'webjslint.js' no valida, aunque la mayoría de los errores que veo ahora tienen que ver con el espaciado. Claramente, uno debe usar sentido común y juicio razonable al revisar JavaScript usando JSLint. – hotshot309

+0

El uso de la palabra 'siempre' automáticamente descalifica esta cita como sabiduría. Los programadores inteligentes no son dogmáticos. Usan lo mejor en la situación dada. Y aceptan y adoptan cualquier herramienta integrada en el núcleo mismo del lenguaje, no solo lo descartan con un 'simplemente nunca lo toquen'. En pocas palabras: mi código es más corto (y no solo de guardar un carácter '='), por lo tanto, mi sitio se carga más rápido, a un menor costo de ancho de banda, por lo que mi usuario estará mejor atendido. –

22

JSLint es intrínsecamente más defensivo de lo que permite la sintaxis de Javascript.

De la documentación JSLint:

Los == y != operadores lo escriba antes de comparar la coacción. Esto es malo porque causa que ' \t\r\n' == 0 sea verdadero. Esto puede enmascarar errores de tipo.

Cuando se compara con cualquiera de los siguientes valores, utilice las === o !== operadores (que no hace l tipo coerción): 0 '' undefined null false true

Si sólo se preocupan de que un valor es Truthy o Falsy, a continuación, usa la forma corta.En lugar de

(foo != 0)

sólo decir

(foo)

y en lugar de

(foo == 0)

dicen

(!foo)

Se prefieren los operadores === y !==.

+0

Buen recordatorio para usar (! Foo) en lugar de (foo == 0). ¡Gracias! –

+4

Tengo que concluir que las personas de JSLint trabajan en una torre de marfil muy alta de la que nunca salen. Javascript * fue * diseñado * para ser utilizado con el operador '=='. El '===' es un caso especial ... JSLint intenta hacer que parezca que usar '==' de alguna manera sería incorrecto ... Sin embargo, intente esto: 'var x = 4, y = número nuevo (4) ; if (x == y) {alert ('Javascript depende de == simplemente abrázalo!');} '. Los tipos primitivos tienen clases correspondientes que los sustituyen ('Number',' String') y Javascript depende del operador '==' para compararlos. –

12

Triple-igual es diferente a doble igual porque además de comprobar si las dos partes son el mismo valor, de triple igual también comprueba que son el mismo tipo de datos.

Entonces ("4" == 4) es verdadero, mientras que ("4" === 4) es falso.

Triple-equal también se ejecuta un poco más rápido, porque JavaScript no tiene que perder tiempo haciendo conversiones de tipo antes de darle la respuesta.

JSLint tiene el objetivo deliberado de hacer que su código JavaScript sea lo más estricto posible, con el objetivo de reducir errores desconocidos. Destaca este tipo de cosas para tratar de que codifiques de una manera que te obligue a respetar los tipos de datos.

Pero lo bueno de JSLint es que es solo una guía. Como dicen en el sitio, dañará tus sentimientos, incluso si eres un programador de JavaScript muy bueno. Pero no deberías sentirte obligado a seguir su consejo. Si ha leído lo que tiene que decir y lo comprende, pero está seguro de que su código no se va a romper, no hay obligación de que cambie nada.

Incluso puede decirle a JSLint que ignore las categorías de cheques si no desea ser bombardeado con advertencias de que no va a hacer nada al respecto.

+3

No pregunté "¿Qué es ===", así que no estoy seguro de por qué lo respondió? – Metropolis

+6

@Metropolis: si no por otra razón, entonces como fondo en caso de que alguien más lea la respuesta que no sabía. Sin embargo, traté de responder a tu pregunta en los párrafos posteriores. – Spudley

+0

@Spudley + 1 para obtener información adicional y útil –

2

para ayudar a explicar esta pregunta y también explicar por qué NetBeans (de) 7.3 ha comenzado a mostrar esta advertencia se trata de un extracto de la respuesta en el rastreador NetBeans error cuando alguien informó de esto como un error:

Es bueno practique usar === en lugar de == en JavaScript.

Los operadores == y! = Escriben coerción antes de comparar. Esto es malo porque hace que '\ t \ r \ n' == 0 sea verdadero. Esto puede enmascarar errores de tipo. JSLint no puede determinar de manera confiable si == se está utilizando correctamente, por lo que es mejor no usar == y! = En absoluto y usar siempre los operadores más confiables === y! == en su lugar.

Reference

+1

Encontré este error ahora también usando Netbeans. Es extraño que traten esto con severidad de advertencia debido al caso de ejemplo extraño que proporcionaron. – oMiKeY

+0

@oMiKeY ¿Qué quieres decir? Me parece correcto. –

+1

quiero decir, es cierto, pero hay muchos casos de uso en los que la persona sabe que las dos cosas comparadas serán del mismo tipo, por lo que parece extraño que debido a este extraño caso en el que un retorno de carro se pueda comparar con el número cero es la razón por la que todos los usos de == se consideran incorrectos. Sin embargo, estoy descubriendo que === es más rápido, ya que no se realizan conversiones de tipo. Estoy sorprendido de que no haya descubierto esto antes de Netbeans. – oMiKeY

2

Si desea probar para falsyness. JSLint no permite

if (foo == null) 

pero permite

if (!foo) 
+0

Use '===', que JSLint recomienda. –

+1

@NarawaGames Esta solución es perfectamente aceptable. –

+0

Esta respuesta no es buena. El caso es que ambos significan algo más. 'foo == null' comprueba nulo o indefinido. '! foo' busca nulo, indefinido, 0 y cadena vacía. – Markos

Cuestiones relacionadas