Альтернатива JavaScript

Я не очень доволен JavaScript.

Тут какой-то плач:

  • нет заданных операций
  • наследование не такое простое, как в Python
  • определения вложенных функций, обратные вызовы, трудно отлаживать

Требуемые функции:

  • Открытый исходный код
  • должен работать в браузере без дополнительного плагина
Я сомневаюсь, что что-то еще существует, по крайней мере, с поддержкой JS. По сути, браузеры уже давно «объявили» JavaScript стандартом де-факто. Текущие браузеры не интерпретируют никакой другой язык. Единственная «альтернатива», о которой я могу думать, — это VBScript, работающий под Internet Explorer, которого больше нигде нет.
@Alejandro AFAIK есть языки, которые «компилируют» в JS. Но я понятия не имею о состоянии искусства.

Ответы (5)

Единственный язык, который может переносимо заполнить текущую цель 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.

Единственным недостатком является то, что можно обмениваться только числами, поэтому в настоящее время передача/возврат объектов и структур требует написания некоторого кода преобразования, но я уверен, что очень скоро для этого появятся некоторые универсальные библиотечные функции.

На самом деле я сделал минимальное количество WebAssembly с Rust. Это... интересная экосистема прямо сейчас. Много болезней роста.
Я ищу некоторые библиотеки для облегчения перевода сложных типов данных. На самом деле, я думаю, что я опубликую вопрос с таким вопросом позже сегодня.
Сделанный. Посмотреть этот вопрос

Существует Brython , который позволяет использовать Python внутри веб-страниц (с чем-то вроде <script type="text/python">). Предостережения:

  1. Это снижает производительность по сравнению с выполнением того же самого в обычном Python или простом JavaScript, особенно во время загрузки страницы.
  2. Есть еще случайные ошибки.
  3. На самом деле это все еще JavaScript; Brython просто компилирует ваш Python в JavaScript. Однако это довольно эффективно скрыто, и код вашего сайта можно написать полностью на Brython без использования «сырого» JavaScript.

Его преимущества:

  1. Он работает без какой-либо специальной поддержки браузера. В отличие от большинства других транспиляторов, он компилируется в JavaScript на лету. Это означает, что вы можете написать код Python в теге <script>вместо того, чтобы прекомпилировать код в JavaScript на отдельном шаге. (Однако именно поэтому он медленный.)
  2. Это открытый исходный код, и разработка, кажется, довольно активна.
  3. Python лучше, чем JavaScript во всех отношениях.
Это выглядит очень интересно. Я потрачу на это некоторое время; по крайней мере, проект hello world. Вы упомянули «штраф за производительность» — у вас есть подробности? если нет, я холодно профилирую свой проект. Но, поскольку вы говорите «особенно во время загрузки страницы», это смягчает мою озабоченность, поскольку большинство моих SPA состоят из серии взаимодействий с пользователем, каждое из которых приводит к некоторому AJAX и обработке результата. Было бы хорошо иметь возможность кодировать большую часть кода на Python, а не на JS.
@Mawg: Вы можете найти больше информации, если покопаетесь на сайте Brython и/или в списке рассылки. Одна из самых больших затрат заключается в том, что (если вы не пытаетесь быть очень умным) Brython должен загружать практически всю стандартную библиотеку Python (в форме JavaScript) во время загрузки страницы; это значительный объем JS-кода, который необходимо передать и запустить. По моему опыту, есть заметная задержка даже при загрузке страницы, которая просто загружает Brython, но на самом деле ничего не делает. Кроме того, ваш собственный код Brython транспилирует в JavaScript на лету (т. е. при каждой загрузке страницы), что также требует времени.
(продолжение...) Тем не менее, я написал небольшое веб-приложение, которое использовало 100% Brython, никакого «настоящего» JavaScript, и это намного приятнее, чем писать на JS. Производительность также имеет тенденцию немного улучшаться с новыми версиями Brython. Я бы посоветовал вам поиграть и попробовать что-нибудь сделать, чтобы посмотреть, можно ли смириться с проблемами производительности в вашем случае использования. В целом Brython определенно заслуживает внимания.

[Я думаю, что мой существующий ответ все еще полезен, но я столкнулся с дополнительной информацией, которая побудила меня дать другой ответ.]

@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.

Мой следующий вопрос: «Вавилон против TypeScript». Но я задам этот вопрос позже, не сегодня.
Пожалуйста, дайте ссылку здесь, когда вы это сделаете. Спасибо

Чтобы решить проблему вложенных определений функций и их обратных вызовов, вы должны начать использовать понятие обещания javascript, которое довольно приятно - оно устраняет ад обратных вызовов.

javascript ES6 обрабатывает набор операций, см. http://2ality.com/2015/01/es6-set-operations.html .