Soy cauteloso de hacer esta pregunta porque puede parecer demasiado exigente. Acabo de abrir JavaScript: la guía definitiva, y dice que en la primera página del capítulo 1
"JavaScript es un lenguaje de programación interpretado de alto nivel, dinámico y sin tipo"
Entonces, ¿debo considerar que la parte interpretada es un requisito en la especificación del lenguaje, o es engañoso decir que el lenguaje es un lenguaje de programación interpretado cuando se respeta la diferencia entre un lenguaje y sus múltiples implementaciones?
Aparentemente no hay compiladores estáticos para JavaScript: https://stackoverflow.com/questions/1118138/is-there-a-native-machine-code-compiler-for-javascript, así que tal vez sea solo un reflejo de esto.
javascript
Matt Esch
fuente
fuente
Respuestas:
Los geeks del lenguaje EcmaScript a menudo usan el término "intérprete de ES" para referirse a una implementación de EcmaScript, pero la especificación no usa ese término. El resumen del lenguaje en particular describe el lenguaje en términos independientes del intérprete:
Por lo tanto, EcmaScript asume un "entorno host" que se define como un proveedor de definiciones de objetos, incluidos todos aquellos que permiten E / S o cualquier otro enlace al mundo exterior, pero no requiere un intérprete.
La semántica de las declaraciones y expresiones en el lenguaje se define en términos de especificación de finalización que se implementan trivialmente en un intérprete, pero la especificación no requiere eso.
Las transferencias de control no locales se pueden convertir en matrices de instrucciones con saltos que permiten la compilación nativa o de código de bytes.
"Motor EcmaScript" podría ser una mejor manera de expresar la misma idea.
Esto no es verdad. El "intérprete" V8 compila el código nativo internamente, Rhino compila opcionalmente el código de bytes de Java internamente y varios intérpretes de Mozilla ({Trace, Spider, Jager} Monkey) usan un compilador JIT.
V8 :
Rinoceronte :
TraceMonkey :
fuente
de-optimization
pasos. En otras palabras, JavaScript es compilado por estos motores, pero no está compilado estáticamente.La V8 JavaScript VM utilizada en Chrome no incluye un intérprete. En cambio, consta de dos compiladores y compila el código sobre la marcha. Uno de los compiladores se ejecuta rápidamente pero genera código ineficiente, el otro es un compilador optimizador.
Puedo entender por qué algunas personas considerarían esta "trampa", ya que V8 toma el código fuente como entrada cada vez que se ejecuta el código y el usuario debe tener instalado V8. Pero considere un compilador que emite un ejecutable que incluye un intérprete completo y un código de bytes. Entonces tendrías un programa independiente. Simplemente no sería muy eficiente.
fuente
La aparición de compiladores JIT para lenguajes de script ha desdibujado la línea entre la compilación y la interpretación hasta un punto donde la pregunta no significa mucho. ¿Es solo interpretación cuando el motor lee una línea de código y la ejecuta inmediatamente? (Los scripts de Shell todavía se implementan normalmente de esta manera.) ¿Es una interpretación cuando el motor toma todo el archivo, lo compila inmediatamente en algún código de byte y luego interpreta el código de byte? (El motor Mozilla de primera etapa funciona de esta manera, al igual que CPython). ¿Es interpretación cuando el motor analiza una función a la vez y JIT la compila en código nativo? ¿Qué pasa con esos motores que compilan todo el archivo en código de bytes, luego JIT una función a la vez según sea necesario? (La mayoría de los motores de script en estos días funcionan de esta manera,
Hay muchos matices entre la compilación y la interpretación.
Creo que la definición más útil para la interpretación es "se alimenta el código fuente del programa en el momento de la ejecución, sin un paso por adelantado por separado". Según esta definición, todos los motores de JavaScript son intérpretes. Pero esta ciertamente no es la única definición posible de interpretación.
¿Pero está diseñado JavaScript para la interpretación? En cierto modo, sí: tiene una
eval
función, así como elFunction
constructor, que puede dar código de programa como una cadena que se ejecutará. La capacidad de construir dinámicamente el código del programa en tiempo de ejecución requiere que el motor sea capaz de interpretar el código fuente. Pero esto no significa que no pueda hacer todo lo demás con anticipación. Incluso en un lenguaje compilado como C ++ y C #, puede tomar el código fuente, compilarlo en la memoria en un nuevo código de máquina y luego ejecutarlo. Incluso hay bibliotecas para eso: LLVM + Clang en C ++ y el proyecto Roslyn en C #.Además, el mecanismo de entrega de JavaScript es el código fuente; no hay una forma de código de byte reconocida. C # y Java tienen su código de byte oficial, y todos esperan que C ++ se entregue como código de máquina. Pero este aún no es un aspecto inherente al lenguaje, solo un escenario de uso dominante. De hecho, el cercano ActionScript en Flash de JavaScript se entrega como código de bytes (el compilador de Flash precompila todos los scripts).
fuente
No existe una definición totalmente acordada de 'interpretado' versus 'compilado'. En la distinción clásica, los lenguajes compilados producen un ejecutable binario independiente, mientras que los lenguajes interpretados requieren un tiempo de ejecución desplegado para ejecutar el código. Las máquinas virtuales, el código de bytes, etc., borra la distinción.
Pero aquí hay una definición posiblemente útil: un lenguaje interpretado es un lenguaje en el que el tiempo de ejecución del lenguaje estándar puede tomar el texto del código fuente como entrada y ejecutarlo. Según esa definición, se interpretan Perl, Python, Ruby, JavaScript y scripts de shell y similares (incluso si usan pasos intermedios como bytecode o incluso código nativo). Java, C #, C etc. no lo son. Y JavaScript se interpreta por definición, incluso si la especificación no usa la palabra exacta.
fuente