Sou cauteloso ao fazer esta pergunta porque ela pode parecer excessivamente exigente. Acabei de abrir o JavaScript: The Definitive Guide, e ele afirma na primeira página do capítulo 1
"JavaScript é uma linguagem de programação interpretada de alto nível, dinâmica e sem tipo"
Então, devo considerar que a parte interpretada é um requisito na especificação da linguagem ou é enganoso dizer que a linguagem é uma linguagem de programação interpretada quando se respeita a diferença entre uma linguagem e suas muitas implementações?
Aparentemente, não há compiladores estáticos para JavaScript - https://stackoverflow.com/questions/1118138/is-there-a-native-machine-code-compiler-for-javascript , talvez seja apenas um reflexo disso.
javascript
Matt Esch
fonte
fonte
Respostas:
Os geeks da linguagem EcmaScript costumam usar o termo "intérprete de ES" para se referir a uma implementação do EcmaScript, mas a especificação não usa esse termo. A visão geral do idioma, em particular, descreve o idioma em termos agnósticos de intérpretes:
Portanto, o EcmaScript assume um "ambiente host" que é definido como um provedor de definições de objetos, incluindo todos aqueles que permitem E / S ou quaisquer outros links para o mundo externo, mas não exigem um intérprete.
A semântica de instruções e expressões na linguagem é definida em termos de especificação de conclusão que são implementadas trivialmente em um intérprete, mas a especificação não exige isso.
As transferências de controle não locais podem ser convertidas em matrizes de instruções com saltos, permitindo a compilação nativa ou de código de bytes.
"Mecanismo EcmaScript" pode ser a melhor maneira de expressar a mesma idéia.
Isso não é verdade. O "intérprete" da V8 compila internamente o código nativo, o Rhino opcionalmente compila internamente o bytecode Java e vários intérpretes Mozilla ({Trace, Spider, Jager} Monkey) usam um compilador JIT.
V8 :
Rinoceronte :
TraceMonkey :
fonte
de-optimization
etapas. Em outras palavras, o JavaScript é compilado por esses mecanismos, mas não é estaticamente compilado.A VM JavaScript V8 usada no Chrome não inclui um intérprete. Em vez disso, consiste em dois compiladores e compila o código rapidamente. Um dos compiladores é executado rapidamente, mas gera código ineficiente, o outro é um compilador de otimização.
Eu posso entender por que algumas pessoas considerariam essa "trapaça", pois a V8 recebe o código-fonte como entrada toda vez que o código é executado e o usuário precisa ter o V8 instalado. Mas considere um compilador que emite um executável que inclua um intérprete e um bytecode completos. Então você teria um programa independente. Simplesmente não seria muito eficiente.
fonte
O surgimento de compiladores JIT para linguagens de script obscureceu a linha entre compilação e interpretação a um ponto em que a pergunta não significa muito. É apenas interpretação quando o mecanismo lê uma linha de código e a executa imediatamente? (Geralmente, os scripts de shell ainda são implementados dessa maneira.) É interpretação quando o mecanismo pega o arquivo inteiro, o compila imediatamente em algum código de byte e depois interpreta o código de byte? (O mecanismo Mozilla de primeiro estágio funciona dessa maneira, assim como o CPython.) É interpretação quando o mecanismo analisa uma função de cada vez e o JIT a compila no código nativo? E os mecanismos que compilam o arquivo inteiro em código de bytes e, em seguida, JIT uma função por vez, conforme necessário? Atualmente, a maioria dos mecanismos de script funciona dessa maneira,
Existem muitos tons entre compilação e interpretação.
Eu acho que a definição mais útil para interpretação é "é alimentado o código fonte do programa no tempo de execução, sem uma etapa antecipada separada". Por essa definição, todos os mecanismos JavaScript são intérpretes. Mas essa certamente não é a única definição possível de interpretação.
Mas o JavaScript foi projetado para interpretação? De certa forma, sim: ele possui uma
eval
função e oFunction
construtor que você pode fornecer ao código do programa como uma string que será executada. A capacidade de construir dinamicamente o código do programa em tempo de execução requer que o mecanismo seja capaz de interpretar o código-fonte. Mas isso não significa que você não pode fazer todo o resto antes do tempo. Mesmo em uma linguagem compilada como C ++ e C #, você pode pegar o código-fonte, compilá-lo na memória para um novo código de máquina e depois executá-lo. Existem até bibliotecas para isso: LLVM + Clang em C ++ e o projeto Roslyn em C #.Além disso, o mecanismo de entrega para JavaScript é o código-fonte; não existe uma forma de código de bytes reconhecido. C # e Java têm seu código de bytes oficial e todos esperam que o C ++ seja entregue como código de máquina. Mas esse ainda não é um aspecto inerente à linguagem, apenas um cenário de uso dominante. De fato, o ActionScript relativamente próximo do JavaScript no Flash é realmente entregue como código de bytes (o compilador do Flash pré-compila todos os scripts).
fonte
Não existe uma definição totalmente acordada de 'interpretado' versus 'compilado'. Na distinção clássica, as linguagens compiladas produzem um executável binário independente, enquanto as linguagens interpretadas requerem um tempo de execução implantado para executar o código. Máquinas virtuais, bytecode e assim por diante desfocam a distinção.
Mas aqui está uma definição possivelmente útil: Uma linguagem interpretada é uma linguagem em que o tempo de execução do idioma padrão é capaz de pegar o texto do código-fonte como entrada e executá-lo. Por essa definição, scripts Perl, Python, Ruby, JavaScript e shell e similares são interpretados (mesmo que usem etapas intermediárias como bytecode ou mesmo código nativo). Java, C #, C etc. não são. E o JavaScript é interpretado por definição, mesmo que a especificação não use a palavra exata.
fonte