Top 10 cosas que JavaScript se equivocó

JavaScript, aunque solo sea por defecto, es uno de los lenguajes de programación más populares disponibles. A lo largo de los años, ha sido calificado como una pesadilla para trabajar, y, hasta cierto punto, ¡esto es cierto! Sin embargo, la mayoría de las veces, lo que la gente quiere decir es que la API DOM es una pesadilla. Sin embargo, hay un puñado de errores en el lenguaje.

Me gustaría hacer una nota que me encanta JavaScript. Este artículo solo es para divertirse y para que seamos conscientes de algunas de sus fallas.

1. El Nombre. JavaScript no es Java

Comenzaremos con un jab divertido en la elección del nombre. Aunque originalmente se llamaba Mocha y luego LiveScript, más tarde se cambió a JavaScript. Según la historia, sus similitudes con el nombre de Java fueron el resultado de una colaboración entre Netscape y Sun, a cambio de que Netscape incluyera el tiempo de ejecución de Java en su popular navegador. También se ha notado que el nombre vino, casi como una broma, debido a la rivalidad entre LiveScript y Java para las secuencias de comandos del lado del cliente..

Sin embargo, resultó en miles de comentarios de "JavaScript no tiene nada que ver con Java" en foros de toda la web.!

2. Nulo es un objeto.?

Considera esto…

 console.log (typeof null); // objeto

Esto tiene sentido cero. Si nulo es la ausencia de un valor, ¿cómo podría su tipo ser "objeto"? La respuesta simple es que se trata de un error que se remonta a la primera versión de JavaScript, que incluso se transfirió incorrectamente a JScript de Microsoft..

3. NaN! == NaN

NaN, como es de esperar, se refiere a un valor que no es un número legal. El problema es que NaN no es igual a nada ... incluso a sí mismo.

 console.log (NaN === NaN); // falso

Esto debería estar mal. En cambio, si desea determinar si un valor es realmente NaN, puede usar la función isNaN ().

Actualizar: después de leer algunos de los comentarios brillantes, particularmente los relacionados con NaN que son similares al infinito, entonces tiene perfecto sentido que NaN no sea igual a sí mismo. Pero todavía puede ser confuso. Consulte los comentarios para una discusión en profundidad sobre este!

4. Variables globales

Se considera ampliamente que la dependencia de las variables globales es, de lejos, la peor parte de JavaScript. Para proyectos simples, como los consejos rápidos en este sitio, realmente no hace una diferencia. Sin embargo, la carga real de los elementos globales entra en juego cuando comienza a hacer referencia a varios scripts, sin ningún conocimiento de cómo se crean o se nombran. Si sucede que comparten el mismo nombre que una de sus variables, su programa producirá algún tipo de error..

"El problema con JavaScript no es solo que los permite (variables globales), los requiere". - Crockford

5. Informe de cadenas de usuario-agente Mozilla. Siempre me pregunto por qué?

Bien, este no es culpa de JavaScript. Hice trampa un poco. Es debido a los proveedores de navegador. Dicho esto, la detección de cadenas de usuario-agente es muy común en JavaScript; por lo que es importante saber con qué estás tratando. Probablemente no pertenece a esta lista, pero a quién le importa! Es bueno saberlo.

Este no es tanto un error como una decisión inevitable. Por ejemplo, abra Safari, acceda al inspector web y registre la cadena del agente de usuario en la consola.

 console.log (navigator.userAgent); // Mozilla / 5.0 (Macintosh; U; Intel Mac OS X 10_5_8; es-es) AppleWebKit / 531.21.8 (KHTML, como Gecko) Versión / 4.0.4 Safari / 531.21.10

Tenga en cuenta que la primera cadena de caracteres: Mozilla / 5.0. ¿Por qué Safari lo identificaría como un navegador basado en Mozilla? Aunque luego se identifica correctamente, eso todavía no explica por qué se molestan en engañar a los programadores. De hecho, encontrarás que la mayoría de los navegadores se identifican como Mozilla. La respuesta se remonta a una década, y es, nuevamente, menos un error y más una circunstancia inevitable..

Para aquellos que no están familiarizados, una cadena de usuario-agente simplemente pretende identificar el navegador y su versión. Como ejemplo, el primer navegador de la historia, Mosaic, tenía una cadena de usuario-agente que se veía así:

 Mosaico / 0.9 // nombre del navegador / número de versión

Esto tiene perfecto sentido. Y cuando Netscape entró en escena, mantuvieron el uso de Mosaic y también agregaron una sección de tipo de cifrado.

 Mozilla / 2.02 [en] (Win95; I) // nombre / versión / cifrado del navegador

Hasta ahora tan bueno. Los problemas entraron en juego cuando se lanzó Internet Explorer 3. Tenga en cuenta que, cuando se lanzaron, Netscape era el navegador más popular disponible. De hecho, muchos servidores y programas ya estaban implementando la detección de usuario-agente para identificar a Netscape. Aunque este es un tema muy debatido hoy, en aquel entonces, no era un gran problema. Si IE hubiera usado su propia cadena de usuario-agente, habría parecido algo así:

 MSIE / 3.0 (Win95; U)

Esto los habría dejado en una gran desventaja., porque Netscape ya estaba siendo identificado por muchos servidores. Como tales, los desarrolladores decidieron identificar incorrectamente el navegador como Mozilla y luego agregar un conjunto adicional de información que lo etiqueta como Internet Explorer.

 Mozilla / 2.0 (compatible; MSIE 3.0; Windows 95)

Hoy en día, la detección de usuario-agente es un último esfuerzo, y se considera tan precisamente por esta razón. Encontrarás que la mayoría de los navegadores siguieron el ejemplo de IE para identificarse como Mozilla. Piensa en ello como una reacción en cadena..

Otras lecturas

Le recomiendo que lea la "Historia de la cadena de usuario-agente" de Nicholas Zakas, si desea profundizar más.

6. Inconsistencias del alcance

Considere el siguiente código:

 // Cree una función que llame a una función con el nombre igual al parámetro fn. function foo (fn) if (typeof fn === "function") fn ();  // Crear un objeto con una propiedad y un método. var bar = barbar: "Hello, World!", método: function () alert (this.barbar); ; bar.method (); // Alertas ¡Hola mundo! foo (método de barra); // Si llamamos a la función foo add pasa el método "bar.method", de alguna manera alerta "indefinido". foo (function () bar.method ();); // alertas Hola, mundo, después

La razón por la que foo (bar.method) no genera el mismo resultado es porque la función del método se llamará como un método del objeto de ventana, en lugar de una barra. Para solucionar esto, debemos llamar a bar.method () desde la función anónima pasada.

Muchas gracias a Jeremy McPeak por notificarme este error..

7. El uso de los operadores de Bitwise

JavaScript comparte muchas similitudes con Java, uno de ellos es el conjunto de operadores bitwise.

  • Y - y
  • | - o
  • ^ - xor
  • ~ - no
  • >> - cambio a la derecha firmado
  • ??? - cambio a la derecha sin firmar
  • << - Shift izquierdo

Considere el primer elemento, &; sería mucho más eficiente usar el operador &&, ya que es más rápido. Esto se debe a que JavaScript no es lo mismo que Java y no tiene enteros. Como tal, se requiere un proceso relativamente largo para convertir el operando, hacer algo con él y luego volver a convertirlo.

Esta es la razón por la que puede usar y para "y", y | para "o" - aunque debería usar && y ||.

8. Demasiados valores falsos / inferiores

Tal vez esto no sea específicamente un error en JavaScript, pero ciertamente hace que el proceso de aprendizaje, especialmente para los principiantes, sea difícil. Valores como nulo, falso e indefinido casi significan lo mismo, pero hay diferencias que pueden ser confusas de entender..

Valores de Falsía

Para probar, abra la consola en Firefox y busque el booleano de los siguientes elementos.

 !!(0); // falso !! (falso); // false !! ("); // false !! (null); // false !! (undefined); // false !! (NaN); // false

Tenga en cuenta que cualquier otro valor será interpretado como veraz..

Más que un error, estos muchos valores falsos son confusos.!

9. No puede hacer aritmética

De acuerdo, de acuerdo. Estoy bromeando al 99% con el encabezado de arriba. Pero JavaScript tiene algunos problemas menores cuando se trabaja con decimales, por ejemplo, cosas como transacciones de dinero. Por ejemplo, abra su consola y registre ".2 + .4". Esperamos que muestre ".6", ¿correcto? Pues lo hace, y no lo hace.!

 console.log (.2 + .4); // 0.6000000000000001

¿Cómo? En un nivel alto, se debe a que JavaScript usó el estándar IEEE para la aritmética de punto flotante binario. Probablemente, como usted, no entiendo exactamente lo que eso especifica, pero sé que, cuando se trata de fracciones decimales, los resultados pueden variar ligeramente de lo que podría esperar. Tenga en cuenta que la aritmética de enteros es perfecta, por lo que realmente no es un gran problema.

10. Código de estilo no es su elección!

Cuando se trata de su estilo de codificación, es exactamente eso: tu estilo. Algunas personas prefieren colocar sus llaves en la misma línea que el control, otras prefieren que se vaya por sí sola..

 // llaves a la derecha devuelve foo: bar; // llaves en su propia línea return foo: bar;

Dependiendo del primer libro de desarrollo web que leemos, o de cómo nuestro maestro nos enseñó, es perfectamente aceptable utilizar cualquiera de los métodos anteriores, o incluso una combinación de los dos. El problema con JavaScript es que no es tu elección!

Aprendí este ejemplo particular de una conferencia que dio Doug Crockford hace aproximadamente un año. Considere la declaración de retorno de arriba. Lo creas o no, no son iguales. No me crees Probar esto. Agrega lo siguiente a alguna página HTML.

 var foo = function () return a: 'b';  (); alerta (foo.a); // b

El código anterior simplemente crea una variable llamada foo, que es igual al objeto devuelto. Cuando alertamos (foo.a), nosotros, como se espera, vemos un cuadro de alerta con un valor de 'b'. Ahora, simplemente tome esa llave de apertura de la declaración de retorno y empújela hacia su propia línea, como así.

 devuelve a: 'b';

Si lo ejecutas nuevamente en tu navegador, recibirás un error de Firebug, al registrar que "foo no está definido". ¿¡Que demonios!? :)

Entonces, ¿por qué JavaScript hace esto? Es debido a algo llamado "inserción de punto y coma". Esencialmente, JavaScript intentará corregir nuestra mala codificación. Si, por ejemplo, piensa que ha dejado un punto y coma de cierre, seguirá adelante y lo agregará por usted. Aunque originalmente fue pensado para ser una conveniencia, especialmente para los nuevos JavaScripters, en realidad es algo muy malo cuando no tienes control sobre tu propio código, como se demostró anteriormente.

En nuestro ejemplo, no hay manera de determinar por qué foo.a devuelve "indefinido". Ahora que estamos conscientes de la inserción de punto y coma, la razón por la que no está definido es porque JavaScript agregará un punto y coma al final de la declaración de devolución.

 regreso; // JS agrega incorrectamente este punto y coma. a: 'b'; // También agregará un punto y coma aquí, porque no se da cuenta de que esto es un objeto. ;

Entonces, si regresamos de inmediato, no tiene idea de lo que la propiedad "a" es, por lo tanto, resulta en "indefinido".

Conclusión

Como mencioné al principio de este artículo, me encanta JavaScript y lo uso a diario. Pero eso no significa que no haya errores realmente horribles en el idioma. Me encantaría escuchar tus pensamientos en los comentarios! Gracias por leer. ¡Retweets y Diggs son siempre apreciados! Muchas gracias a Jeremy McPeak, Doug Crockford, Nicholas Zakas y John Resig: me referí a sus tutoriales y libros al preparar este artículo.

  • Síganos en Twitter o suscríbase a Nettuts + RSS Feed para obtener los mejores tutoriales de desarrollo web en la web..