Я осторожно задаю этот вопрос, потому что он может показаться слишком разборчивым. Я только что открыл JavaScript: Полное руководство, и в нем говорится о первой странице главы 1
«JavaScript - это высокоуровневый, динамический, нетипизированный интерпретируемый язык программирования»
Поэтому я должен считать, что интерпретируемая часть является требованием в спецификации языка, или вводить в заблуждение утверждение о том, что язык является интерпретируемым языком программирования, учитывая разницу между языком и множеством его реализаций?
По-видимому, для JavaScript нет статических компиляторов - https://stackoverflow.com/questions/1118138/is-there-a-native-machine-code-compiler-for-javascript, так что, возможно, это просто отражение этого.
javascript
Мэтт Эш
источник
источник
Ответы:
Специалисты по языку EcmaScript часто используют термин «интерпретатор ES» для обозначения реализации EcmaScript, но в спецификации этот термин не используется. Обзор языка , в частности , описывает язык переводчика-агностик условиях:
Таким образом, EcmaScript предполагает «хост-среду», которая определяется как поставщик определений объектов, включая все те, которые разрешают ввод-вывод или любые другие ссылки на внешний мир, но не требуют интерпретатора.
Семантика операторов и выражений в языке определяется в терминах спецификации завершения, которые тривиально реализуются в интерпретаторе, но в спецификации это не требуется.
Нелокальные передачи управления могут быть преобразованы в массивы инструкций с переходами, позволяющими компилировать собственный или байт-код.
«Механизм EcmaScript» может быть лучшим способом выразить ту же идею.
Это неправда. «Интерпретатор» V8 внутренне компилируется в собственный код, Rhino дополнительно компилируется внутри байт-кода Java, а различные интерпретаторы Mozilla ({Trace, Spider, Jager} Monkey) используют JIT-компилятор.
V8 :
Rhino :
TraceMonkey :
источник
de-optimization
шаги. Другими словами, JavaScript компилируется этими движками, но статически не компилируется.Виртуальная машина JavaScript V8, используемая в Chrome, не содержит интерпретатора. Вместо этого он состоит из двух компиляторов и компилирует код на лету. Один из компиляторов работает быстро, но генерирует неэффективный код, другой - оптимизирующий компилятор.
Я могу понять, почему некоторые люди считают это «мошенничеством», поскольку V8 принимает исходный код в качестве входных данных при каждом запуске кода, и пользователь должен установить V8. Но рассмотрим компилятор, который испускает исполняемый файл, который включает полный интерпретатор и байт-код. Тогда у вас будет отдельная программа. Это просто не было бы очень эффективно.
источник
Появление JIT-компиляторов для языков сценариев размыло грань между компиляцией и интерпретацией до такой степени, что вопрос не так уж много значит. Является ли это только интерпретацией, когда движок читает строку кода и немедленно выполняет ее? (Сценарии оболочки все еще обычно реализуются таким образом.) Является ли это интерпретацией, когда движок берет весь файл, немедленно компилирует его в некоторый байтовый код, а затем интерпретирует байтовый код? (Механизм Mozilla первого этапа работает таким же образом, как и CPython.) Является ли это интерпретацией, когда механизм анализирует функцию за раз и JIT-компилирует ее в собственный код? Как насчет тех движков, которые компилируют весь файл в байтовый код, а затем JIT по одной функции за раз? (Большинство скриптовых движков в наши дни работают так,
Есть много оттенков между компиляцией и интерпретацией.
Я думаю, что наиболее полезным определением для интерпретации является «подача исходного кода программы во время выполнения, без отдельного опережающего шага». По этому определению все движки JavaScript являются интерпретаторами. Но это, конечно, не единственно возможное определение интерпретации.
Но предназначен ли JavaScript для интерпретации? В некотором смысле, да: он имеет
eval
функцию, а такжеFunction
конструктор, который вы можете дать программный код в виде строки, которая будет выполняться. Способность динамически создавать программный код во время выполнения требует, чтобы механизм был способен интерпретировать исходный код. Но это не значит, что вы не можете сделать все остальное раньше времени. Даже в скомпилированном языке, таком как C ++ и C #, вы можете взять исходный код, скомпилировать его в памяти для нового машинного кода и затем выполнить его. Для этого есть даже библиотеки: LLVM + Clang на C ++ и проект Roslyn на C #.Кроме того, механизм доставки для JavaScript является исходным кодом; нет признанной формы байт-кода этого. C # и Java имеют свой официальный байт-код, и все ожидают, что C ++ будет доставлен как машинный код. Но это все еще не неотъемлемый аспект языка, а только сценарий доминирующего использования. Фактически, близкий родственник ActionScript JavaScript во Flash фактически поставляется в виде байтового кода (компилятор Flash предварительно компилирует все сценарии).
источник
Не существует полностью согласованного определения «интерпретированный» или «составленный». В классическом различении скомпилированные языки создают отдельный двоичный исполняемый файл, в то время как для интерпретируемых языков требуется развернутая среда выполнения для выполнения кода. Виртуальные машины, байт-код и так далее стирают различия.
Но вот, возможно, полезное определение: интерпретируемый язык - это язык, на котором стандартная языковая среда выполнения может принимать исходный текст в качестве ввода и выполнять его. По этому определению интерпретируются Perl, Python, Ruby, JavaScript и сценарии оболочки и т.п. (даже если они используют промежуточные этапы, такие как байт-код или даже собственный код). Java, C #, C и т. Д. Не являются. И JavaScript по определению интерпретируется, даже если в спецификации не используется точное слово.
источник