Lo que me molesta de JS es la sintaxis del lenguaje y la semántica. Juntos proporcionan un lenguaje feo y detallado que generalmente es doloroso de leer.
Al usar JS, los programadores deben escribir soluciones para superar los problemas en el lenguaje en sí , y las soluciones son inmensamente complejas y, a menudo, difíciles de entender. La mayoría de estas cosas a las que la gente no quiere preocuparse cuando están tratando de construir software, pero tienen que preocuparse por ellos y se interponen en el camino.
Cosas como:
- ¿Cuál es el valor de una variable? (Ver elevación).
- No hay módulos y soluciones inconsistentes para espacios de nombre y módulos.
- Múltiples formas de construir objetos, todos los cuales parecen estar perdiendo proposiciones de una forma u otra.
- ¿Cuál es el valor de “esto”?
- ¿Usando métodos en objetos o métodos prototipo, o ambos?
- Alcance contraintuitivo. (Sin ámbito de aplicación).
- Igualdad de cualquier cosa.
Esta es la razón por la que hay tantas bibliotecas e idiomas de transpilación que limpian la sintaxis y la semántica de JS, o permiten que los programadores utilicen lenguajes completamente diferentes. Incluso las personas a quienes les gusta escribir en JS necesitan escribir transpilers y lenguajes completamente nuevos para que puedan entender y organizar su código más fácilmente.
- ¿Es cierto que la mayoría de los británicos odian a los inmigrantes pero aman el NHS?
- ¿Los indios odian el inglés?
- Odio a mi familia por ocultar que era autista. ¿Qué tengo que hacer?
- ¿Debo huir porque odio a mi hermano?
- ¿Qué debo hacer si odio mi trabajo de MNC?
Obviamente, ningún lenguaje viene sin cierto nivel de complejidad. Sin embargo, opino que otros idiomas tienen semánticas más simples y elementos de lenguaje con definiciones explícitas, lo que facilita su uso.
Aquí hay un ejemplo con respecto a la semántica y los elementos explícitos del lenguaje. Java tiene clases. Las clases contienen métodos y campos. Los métodos y los campos se pueden declarar como parte de la clase (estática) o como miembros de la instancia. Los métodos y campos tienen modificadores de acceso. Desde las clases se pueden instanciar objetos. Los objetos tienen constructores que están definidos de la misma manera. Hay muchos más elementos de lenguaje para implementar la herencia, etc. El punto es que todos estos elementos de lenguaje se hacen explícitos. Las clases son el elemento base de la abstracción, y los elementos de los que están compuestos se identifican claramente con sus propios nombres y semántica.
A la inversa, JavaScript tiene objetos y funciones (que también son objetos) y variables (que pueden apuntar a objetos, que de nuevo pueden ser funciones), y los objetos no son realmente objetos, son matrices asociativas. El programador implica diferentes semánticas dependiendo de la forma en que combinan y anidan estas cosas. Esto significa que el significado de código es implícito. Combine esto con la semántica de alcance y los cierres, y obtendrá lo que yo llamo la “complejidad combinatoria” de JavaScript. La complejidad combinatoria puede tener un significado en otra parte, pero mi uso se refiere al uso de los mismos elementos en diferentes combinaciones que tienen significados implícitos.
Cuando pienso en JavaScript lo pienso de esta manera:
En inglés podría decir, “voy a la tienda”, porque el inglés tiene diferentes tipos de palabras que me permiten construir oraciones.
En JavaScript, es posible que solo tengamos una palabra, la palabra “Tienda”, por lo que podría decir “Tienda” para que signifique “Me voy a la tienda”.
En inglés podría decir: “Me voy de la tienda”.
En JavaScript, diría, “Tienda tienda”, que significa que me voy de la tienda, y así sucesivamente.
Tal vez decir: “La tienda se quemó y ya no hay más de tu sopa favorita”, en JavaScript, podría escribir “Tienda” 99 veces. Para inferir cualquier significado, el lector tendría que leer / contar la oración y solo al encontrar la “Tienda” número 99 sabría lo que estoy diciendo.
Así es como me siento cuando leo funciones envueltas en funciones, envueltas en cierres, envueltas en expresiones de funciones invocadas de inmediato, envueltas en quién sabe qué otra cosa puede inferir que el programador está tratando de hacer un módulo, o algo así.
Las metáforas mixtas de JavaScript (procedimental, funcional, orientada a objetos) no facilitan las cosas. Dependiendo de cómo combine un solo bloque de construcción (funciones), puede crear una abstracción en cualquiera de esas metáforas. Se requiere mucho esfuerzo para comprender qué implica el código.
Cosas como el patrón del módulo y otros intentos de crear ámbitos privados con estado y razonamiento localizados que usan cierres y funciones envueltas en funciones, envueltas en funciones, son una locura. Se convierte en un caos de razonamiento implícito, es decir, “si envuelve un grupo de funciones de esta manera, implica que el alcance es como tal y que estas variables pertenecen a esta parte del código, y no debe tocar estas variables y no debería tocarlas. No llames a este método así porque se romperá “. Debe leer el código con mucho cuidado y seguir todas las funciones y cierres para conocer el significado implícito del programador.
Compare esto con algo como Java, donde tiene elementos de lenguaje explícitos como clases para denotar el alcance local, los métodos con alcance de método, los bloques con alcance de bloque y los modificadores de acceso para controlar la privacidad. El lenguaje deja muy claro cuál es la intención del programador, y es inmediatamente reconocible.
La gente sostiene que quejarse JS no tiene clases es un sesgo de usar lenguajes OO compilados basados en clases, pero no se trata de clases. Se trata de elementos de lenguaje claros y explícitos, que permiten a los programadores leer el código y entenderlo rápidamente.
Si quiero crear una unidad de código con alcance local que pueda ser instanciada, entonces debería haber un elemento de nivel de lenguaje explícito y partes explícitas relacionadas para hacer eso, no una combinación del mismo elemento de lenguaje para crear un patrón implícito. Un lenguaje debe otorgar a los programadores control sobre el código y la capacidad de evitar que las funciones y los datos se filtren por todo el lugar al proporcionar elementos de apoyo. JavaScript no hace eso.
Aquí hay algunas citas de Wikipedia que muestran algunas de las rarezas, y cómo JavaScript es particularmente confuso:
JavaScript está casi enteramente basado en objetos. Los objetos de JavaScript son matrices asociativas, aumentadas con prototipos (ver más abajo). Los nombres de las propiedades de los objetos son claves de cadena. –
Un objeto ni siquiera es un objeto en JS. Es una matriz asociativa aumentada con un prototipo, y es importante que los programadores comprendan este detalle de implementación para usar el lenguaje correctamente.
Las funciones son de primera clase; son objetos en sí mismos. Como tales, tienen propiedades y métodos, como .call () y .bind (). -JavaScript
Una función anidada es una función definida dentro de otra función. Se crea cada vez que se invoca la función externa. Además, cada función creada forma un cierre léxico … -JavaScript
Sé que a todos les gusta hablar sobre cierres, pero nuevamente este es un ejemplo de la complejidad combinatoria. Terminas con un código como este:
var elems = document.getElementsByTagName (‘a’);
para (var i = 0; i <elems.length; i ++) {
elems [i] .addEventListener (‘click’, (function (lockedInIndex) {
función de retorno (e) {
e.preventDefault ();
alerta (‘I link #’ + lockedInIndex);
};
}) (i), ‘falso’);
}– Expresión de función invocada inmediatamente (IIFE)
Las funciones se doblan como constructores de objetos junto con su función típica. El prefijo de una llamada de función con una nueva creará una instancia de un prototipo, heredando propiedades y métodos del constructor … A diferencia de muchos lenguajes orientados a objetos, no hay distinción entre una definición de función y una definición de método. Más bien, la distinción se produce durante la llamada a la función; cuando se llama a una función como método de un objeto, la palabra clave local de la función está vinculada a ese objeto para esa invocación.
Más combinaciones creando nuevas semánticas dependientes del uso situacional. Cualquiera que haya programado en JS conoce la molestia de tratar con este enlace.
Creo que una buena parte es que hay una biblioteca JS para todo ahora … jackdcrawford / five