Я не очень доволен JavaScript.
Тут какой-то плач:
Требуемые функции:
Единственный язык, который может переносимо заполнить текущую цель JavaScript в браузерах, — это JavaScript. Убедитесь, что вы используете новейший стандарт ECMAScript (ES2016/2017), и при необходимости используйте транспилятор, такой как BabelJS, для вывода JS в соответствии с более ранним стандартом.
Если вам этого недостаточно, другие языки могут компилироваться в JavaScript.
TypeScript — это надмножество JavaScript (это означает, что все действительные JS являются действительными TS). Тем не менее, он вводит элементы статической типизации и другие абстракции, связанные с типами и наследованием, поверх «стандартного JS» (следуя синтаксису ES2016, где он существует), что обеспечивает более богатые возможности отладки и транспилирует в общий JS, который поддерживает каждый браузер. Это бесплатное приложение с открытым исходным кодом, поддерживаемое Microsoft и являющееся фаворитом Angular. В большинстве популярных IDE есть (а) плагин(ы), которые максимально упрощают разработку TypeScript.
Kotlin — это язык JVM, изначально разработанный как лучшая версия Java и недавно принятый Android в качестве родного языка. Он также имеет первоклассную поддержку цели JS (начиная с 1.1). Если вы действительно хотите использовать настоящий ООП, то это, вероятно, один из лучших вариантов, поскольку Kotlin сначала был производным от Java, а Java (почти) чисто ООП. Конечно, Kotlin также поддерживает код в более функциональном стиле, который в большинстве случаев считается более идиоматичным и набирает все большую популярность во всем мире JS. Kotlin имеет открытый исходный код и разработан JetBrains, создателями IntelliJ IDEA. Официальные плагины для разработки доступны для IDEA и Eclipse, а для большинства других IDE есть плагины от сообщества.
Существуют и другие языки, транспилируемые в JavaScript. Будем надеяться, что когда WebAssembly станет широко поддерживаться, большинство языков смогут поддерживать Интернет в качестве цели компиляции.
По состоянию на декабрь 2017 года все основные браузеры поддерживают WebAssembly. C, C++ и Rust имеют существующие цели для WebAssembly с использованием LLVM и/или EmScripten. WebAssembly все еще молод, и все еще есть проблемы с ростом, но его можно использовать. См. Какие языки можно скомпилировать в веб-сборку (или wasm)? и ответ Мауга на этот вопрос для получения дополнительной информации.
Кроме того, я больше использовал JS с тех пор, как написал этот ответ. Пока вы пишете современный JS с использованием современного синтаксиса, это довольно хорошо. С async/await асинхронный код намного проще обрабатывать, а распространение/деструктурирование также упрощает некоторые вещи. JavaScript действительно становится питоническим.
На дворе январь 2017 года, и та магия WebAssembly, которую я предсказывал, приходит. Вы по-прежнему не можете получить беспрепятственный доступ к веб-API, но с помощью сборщика веб-приложений Parcel с нулевой конфигурацией вы можете просто импортировать (простой) Rust fn в JS !
[Обновление принятого ответа для будущих читателей]:
Как и предсказывал @CAD97, WebAssembly теперь поддерживается во всех основных браузерах.
Если вы хотите уменьшить количество JS, который вы кодируете (вы не можете полностью исключить его), тогда Google для WebAssembly, если вы можете кодировать на C, C++ или Rust.
Вот очень простой пример из этого урока :
Возьмите код C:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <emscripten/emscripten.h>
int main(int argc, char ** argv) {
printf("WebAssembly module loaded\n");
}
int EMSCRIPTEN_KEEPALIVE roll_dice() {
srand ( time(NULL) );
return rand() % 6 + 1;
}
скомпилируйте его в WebAssembly с помощью командыemcc dice-roll.c -s WASM=1 -O3 -o index.js
и вызовите WebAssembly вашего кода C в вашем HTML:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>WebAssembly Example</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<!-- Include the JavaScript glue code. -->
<!-- This will load the WebAssembly module and run its main. -->
<script src="index.js"></script>
</body>
</html>
Для WebAssembly еще рано, но есть хорошие учебные пособия. И, судя по всему, скоро мы будем отлаживать этот C-код в браузере так же, как сегодня отлаживаем JS.
Единственным недостатком является то, что можно обмениваться только числами, поэтому в настоящее время передача/возврат объектов и структур требует написания некоторого кода преобразования, но я уверен, что очень скоро для этого появятся некоторые универсальные библиотечные функции.
Существует Brython , который позволяет использовать Python внутри веб-страниц (с чем-то вроде <script type="text/python">
). Предостережения:
Его преимущества:
<script>
вместо того, чтобы прекомпилировать код в JavaScript на отдельном шаге. (Однако именно поэтому он медленный.)[Я думаю, что мой существующий ответ все еще полезен, но я столкнулся с дополнительной информацией, которая побудила меня дать другой ответ.]
@CAD97 и @Mawg предлагают WebAssembly в качестве потенциальной цели для замены JavaScript в будущем. Однако это не является целью проекта :
WebAssembly пытается заменить JavaScript?
Нет! WebAssembly разработан как дополнение, а не замена JavaScript. В то время как WebAssembly со временем позволит компилировать многие языки в Web, JavaScript обладает невероятной динамикой и останется единственным, привилегированным (как описано выше) динамическим языком Web. Кроме того, ожидается, что JavaScript и WebAssembly будут использоваться вместе в ряде конфигураций:
- Цельные, скомпилированные приложения C++, использующие JavaScript для объединения элементов.
- Пользовательский интерфейс HTML/CSS/JavaScript вокруг основного центрального холста, управляемого WebAssembly, позволяет разработчикам использовать возможности веб-фреймворков для создания доступных веб-приложений.
- В основном приложение HTML/CSS/JavaScript с несколькими высокопроизводительными модулями WebAssembly (например, графики, симуляция, обработка изображений/звука/видео, визуализация, анимация, сжатие и т. д., примеры которых мы уже можем видеть сегодня в asm.js) позволяя разработчикам повторно использовать популярные библиотеки WebAssembly так же, как современные библиотеки JavaScript.
- Когда WebAssembly получит возможность доступа к объектам, собранным из мусора 🦄 , эти объекты будут совместно использоваться с JavaScript, а не будут жить в своем собственном мире, отгороженном стеной.
WebAssembly является дополнением к JavaScript. Предполагаемый вариант использования заключается в том, что библиотеки записываются и компилируются в WASM, а затем вызываются из JS. Но учитывая, что вы сравниваете JS с Python в ОП, вам может быть интересно узнать, что JavaScript становится питоническим !
Классы
Питон:
class Point: def __init__(self, x, y): self.x = x self.y = y def __str__(self): return "({x}, {y})".format(x=self.x, y=self.y)
JavaScript:
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return `(${this.x}, ${this.y})`; } }
Подклассы
Питон:
class ColorPoint(Point): def __init__(self, x, y, color): super().__init__(x, y) self.color = color def __str__(self): return "{super} in color {color}".format( super=super().__str__(), color=self.color )
JavaScript:
class ColorPoint extends Point { constructor(x, y, color) { super(x, y); this.color = color; } toString() { return `${super.toString()} in ${this.color}`; } }
Эти примеры обращаются к вашей болевой точке наследования. Современный JavaScript может выражать классы и наследование почти так же, как Python.
Для операций над наборами см. объект Set ( совместимость ). MDN предлагает базовые реализации операций над наборами :
Set.prototype.isSuperset = function(subset) { for (var elem of subset) { if (!this.has(elem)) { return false; } } return true; } Set.prototype.union = function(setB) { var union = new Set(this); for (var elem of setB) { union.add(elem); } return union; } Set.prototype.intersection = function(setB) { var intersection = new Set(); for (var elem of setB) { if (this.has(elem)) { intersection.add(elem); } } return intersection; } Set.prototype.difference = function(setB) { var difference = new Set(this); for (var elem of setB) { difference.delete(elem); } return difference; }
Или альтернативные неразрушающие реализации:
Set.prototype.union = that => new Set([...this, ...that]) Set.prototype.intersection = that => new Set(this.values().filter(it => that.has(it))) Set.prototype.difference = that => new Set(this.values().filter(it => !that.has(it)))
Вы не можете перегружать операторы, но это потому, что Object + Object
они уже четко определены (чтобы принудить оба оператора к примитивному значению, а затем к +
этим значениям).
Последняя проблема — это трудности с отладкой асинхронного кода JavaScript. К сожалению, в основном это связано с тем, что асинхронный код трудно отлаживать. Однако, если вы используете промисы и async/await , вы можете писать асинхронный код так же, как корутины PEP 492 с async и await . Об асинхронности вообще сложно рассуждать, и JavaScript здесь не виноват.
Хитрость в использовании всех тонкостей современного ECMAScript заключается в том, чтобы использовать Babel для переноса вашего причудливого современного синтаксиса в совместимый с браузером JavaScript. Если вы хотите, чтобы язык, работающий в Интернете, обеспечивал интерактивность веб-сайта, единственным вариантом является JavaScript, по крайней мере, до тех пор, пока WASM не созреет до такой степени, что у него будет GC и взаимодействие объектов с JavaScript, что позволит использовать методы DOM в WASM.
Чтобы решить проблему вложенных определений функций и их обратных вызовов, вы должны начать использовать понятие обещания javascript, которое довольно приятно - оно устраняет ад обратных вызовов.
javascript ES6 обрабатывает набор операций, см. http://2ality.com/2015/01/es6-set-operations.html .
Алехандро
гетли