この記事では、JavaScript にコンパイルしてブラウザーまたは Node.js などのプラットフォームで実行できる 10 個の興味深い言語をリストします。
最新のアプリケーションには、単純な Web サイトとは異なる要件があります。しかし、ブラウザは(ほとんど)利用可能なテクノロジーが固定されたプラットフォームであり、JavaScript は依然として Web アプリケーションの中核言語です。ブラウザーで実行する必要があるアプリケーションはすべて、この言語で実装する必要があります。
JavaScript があらゆるタスクに最適な言語ではないことは誰もが知っており、複雑なアプリケーションとなると不十分になる可能性があります。
この問題を回避するために、新規および既存の言語用にいくつかのトランスポーザーが作成されています。これらはすべて、JavaScript を 1 行も記述せずにブラウザーで動作するコードを生成します。また、使用できる言語には制限があります。考慮する必要があります。
Dart
DART は、すべてがオブジェクトであり、あらゆるオブジェクトがクラスのインスタンスである古典的なオブジェクト指向言語です (オブジェクト関数としても機能します)。これは、ブラウザ、サーバー、モバイル デバイス用のアプリケーションを構築することを目的として構築されています。
これは Google によって管理されており、次世代 Adwords ユーザー インターフェース の推進言語です。これは Google の最も重要な収益製品であり、それ自体が Google が大規模に威力を発揮することを証明しています。
言語はブラウザで使用するために JavaScript に変換したり、Dart VM によって直接解釈したりすることができ、サーバー アプリケーションを構築することもできます。 Flutter SDKを使用してモバイルアプリケーションを作成できます。
複雑なアプリケーションには、そのタスク用に特別に設計された成熟したライブラリと言語機能のセットも必要です。Dart にはそれらがすべて含まれています。人気のあるライブラリの例としては、Dart の Angular バージョンである AngularDart があります。
これを使用すると、あまり問題なくタイプセーフなコードを作成できます。型を記述することもできますが、 * 型は推論できるため、その必要はありません。これにより、詳細についてあまり考えずに迅速なプロトタイピングが可能になりますが、実際に動作するものを作成したら、型を追加してより堅牢にすることができます。
VM での同時プログラミングに関しては、共有メモリ スレッド (Dart はシングルスレッドです) を使用する代わりに、Dart は分離メモリ ヒープと呼ばれるものを使用し、そこで通信はメッセージを使用して実装されます。ブラウザでは状況が少し異なります。新しい分離を作成する代わりに、新しいワーカーが作成されます。
// Example extracted from dartlang.org import 'dart:async'; import 'dart:math' show Random; main() async { print('Compute π using the Monte Carlo method.'); await for (var estimate in computePi()) { print('π ≅ $estimate'); } } /// Generates a stream of increasingly accurate estimates of π. Stream<double> computePi({int batch: 1000000}) async* { var total = 0; var count = 0; while (true) { var points = generateRandom().take(batch); var inside = points.where((p) => p.isInsideUnitCircle); total += batch; count += inside.length; var ratio = count / total; // Area of a circle is A = π⋅r², therefore π = A/r². // So, when given random points with x ∈ <0,1>, // y ∈ <0,1>, the ratio of those inside a unit circle // should approach π / 4. Therefore, the value of π // should be: yield ratio * 4; } } Iterable<Point> generateRandom([int seed]) sync* { final random = new Random(seed); while (true) { yield new Point(random.nextDouble(), random.nextDouble()); } } class Point { final double x, y; const Point(this.x, this.y); bool get isInsideUnitCircle => x * x + y * y <= 1; }
さらに詳しく知りたい場合は、Dart の Dart Getting Started リソースをお勧めします。
#TypeScript
他の多くの言語とは異なり、TypeScript は JavaScript の精神を保持しており、コードの堅牢性を向上させるためにいくつかの機能を追加しているだけです。これらは、静的アナライザーやリファクタリング プロセスを支援するその他のツールなどの特殊なツールのサポートのおかげで、JavaScript の記述をより楽しくする型注釈やその他の型関連の機能です。 さらに、型を追加すると、アプリケーションのさまざまなコンポーネント間のインターフェイスが改善されます。 型推論をサポートしているため、すべての型を最初から作成する必要はありません。簡単なソリューションを作成してからすべての型を追加できるため、コードに自信が持てます。 TypeScript は、交差型、共用体型、型エイリアス、微分共用体、型ガードなどの高度な型 もサポートしています。これらはすべて、TypeScript Documentation サイトの [Advanced Types] ページで表示できます。
react を使用する場合、react タイプを追加することで jsx をサポートすることもできます。class Person { private name: string; private age: number; private salary: number; constructor(name: string, age: number, salary: number) { this.name = name; this.age = age; this.salary = salary; } toString(): string { return `${this.name} (${this.age}) (${this.salary})`; } }
Elm
Elm はJavaScript、HTML、CSS にコンパイルされる純粋な関数型プログラミング言語。 Elm を使用してサイト全体を構築できるため、React などの JavaScript フレームワークの優れた代替手段となります。 これを使用して構築されたアプリは仮想 DOM ライブラリを自動的に使用するため、非常に高速に実行されます。大きな利点は、データ フローを忘れてデータ宣言とロジックに集中できる組み込みアーキテクチャです。 Elm では、すべての関数は純粋関数です。つまり、指定された入力に対して、常に同じ出力が返されます。あなたが指定しない限り、彼らは何もすることができません。たとえば、リモート API にアクセスするには、外部と通信するためのコマンド関数と、応答をリッスンするためのサブスクリプションを作成します。 純粋さのもう 1 つのポイントは、値が不変であるということです。何かが必要なときは、値を変更するのではなく、新しい値を作成します。Elm的采用可以是渐进的。可以使用端口与JavaScript和其他库通信。虽然Elm还没有达到版本1,但是它已经被用于复杂和大型应用程序,这使得它成为复杂应用程序的可行解决方案。
Elm最吸引人的特性之一是初学者友好的编译器,它不是生成难以阅读的消息,而是生成帮助您修复代码的代码。如果你正在学习这门语言,编译器本身会有很大的帮助。
module Main exposing (..) import Html exposing (..) -- MAIN main : Program Never Model Msg main = Html.program { init = init , update = update , view = view , subscriptions = subscriptions } -- INIT type alias Model = String init : ( Model, Cmd Msg ) init = ( "Hello World!", Cmd.none ) -- UPDATE type Msg = DoNothing update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of DoNothing -> ( model, Cmd.none ) -- VIEW view : Model -> Html Msg view model = div [] [text model] -- SUBSCRIPTIONS subscriptions : Model -> Sub Msg subscriptions model = Sub.none
PureScript
purescript是一种纯功能的强类型编程语言,由phil freeman创建。它的目标是提供与可用javascript库的强兼容性,在精神上类似于haskell,但保持javascript的核心。
PureScript的一个优点是它的极简主义。它不包含任何在其他语言中被认为是必不可少的功能库。例如,您可以为任务使用特定的库,而不是在编译器本身中包含生成器和承诺。
您可以为您需要的特性选择您想要的实现,这允许在使用PureScript时获得高效和个性化的体验,同时使生成的代码尽可能小。
它的编译器的另一个独特的特性是,在保持与JavaScript兼容的同时,能够生成干净且可读的代码,包括库和工具。
与其他语言一样,PureScript也有自己的构建工具Pulp,它可以与Gulp进行比较,但是对于用这种语言编写的项目来说。
关于类型系统——不像Elm,它是另一种类似于ml的语言——PureScript支持高级类型特性,比如高级类型和类型类,它们来自Haskell,允许创建复杂的抽象:
module Main where import Prelude import Data.Foldable (fold) import TryPureScript main = render $ fold [ h1 (text "Try PureScript!") , p (text "Try out the examples below, or create your own!") , h2 (text "Examples") , list (map fromExample examples) ] where fromExample { title, gist } = link ("?gist=" <> gist) (text title) examples = [ { title: "Algebraic Data Types" , gist: "37c3c97f47a43f20c548" } , { title: "Loops" , gist: "cfdabdcd085d4ac3dc46" } , { title: "Operators" , gist: "3044550f29a7c5d3d0d0" } ]
要使用purescript执行下一步,请查看github上的purescript入门指南。
CoffeeScript
CoffeeScript是一种语言,旨在公开JavaScript的优秀部分,同时提供更干净的语法和保持语义。尽管近年来该语言的受欢迎程度有所下降,但它正在改变方向,最近又获得了一个新的主要版本,支持ES2015+特性。
您在CoffeeScript中编写的代码将直接转换为可读的JavaScript代码,并保持与现有库的兼容性。 从版本2开始,编译器将生成与最新版本的ECMAScript兼容的代码。
例如,每次使用类时,您都会在JavaScript中获得一个类。 另外,如果您使用React,则有个好消息:JSX与CoffeeScript兼容。
编译器的一个非常独特的功能是能够处理以素养风格编写的代码,您无需在代码中强调重点和添加注释,而是首先编写注释,并且代码仅偶尔出现。 Donald Knuth引入了这种编程风格,使代码文件与技术文章非常相似。
与其他语言不同,CoffeeScript代码可以在浏览器中使用库直接解释。因此,如果你想创建一个快速测试,你可以用text/coffeescript
脚本标签编写代码,并包含编译器,编译器会实时将代码翻译成JavaScript:
# Assignment: number = 42 opposite = true # Conditions: number = -42 if opposite # Functions: square = (x) -> x * x # Arrays: list = [1, 2, 3, 4, 5] # Objects: math = root: Math.sqrt square: square cube: (x) -> x * square x # Splats: race = (winner, runners...) -> print winner, runners # Existence: alert "I knew it!" if elvis? # Array comprehensions: cubes = (math.cube num for num in list)
coffeescript站点有一个方便的coffeescript 2资源入门。
ClojureScript
ClojureScript是一个编译器,它将Clojure编程语言翻译成JavaScript。它是一种通用的函数式语言,具有动态类型和对不可变数据结构的支持。
它是这个列表中唯一属于Lisp编程语言家族的,并且自然地,它共享了许多特性。例如,可以将代码视为数据,并且可以使用宏系统,从而使元编程技术成为可能。与其他lisp不同,Clojure支持不可变的数据结构,这使得副作用的管理更加容易。
由于使用了括号,语法对新手来说可能有些吓人,但这样做有其深刻的原因,从长远来看,您肯定会喜欢它。语法中的这种极简主义及其语法抽象功能使Lisp成为解决需要高抽象级别的问题的强大工具。
虽然Clojure主要是一种函数式语言,但它不像PureScript或Elm那样纯粹。副作用仍然可能发生,但是其他功能特性仍然存在。
ClojureScript使用谷歌闭包进行代码优化,并且与现有的JavaScript库兼容:
; Extracted from https://github.com/clojure/clojurescript/blob/master/samples/dom/src/dom/test.cljs (ns dom.test (:require [clojure.browser.event :as event] [clojure.browser.dom :as dom])) (defn log [& args] (.log js/console (apply pr-str args))) (defn log-obj [obj] (.log js/console obj)) (defn log-listener-count [] (log "listener count: " (event/total-listener-count))) (def source (dom/get-element "source")) (def destination (dom/get-element "destination")) (dom/append source (dom/element "Testing me ") (dom/element "out!")) (def success-count (atom 0)) (log-listener-count) (event/listen source :click (fn [e] (let [i (swap! success-count inc) e (dom/element :li {:id "testing" :class "test me out please"} "It worked!")] (log-obj e) (log i) (dom/append destination e)))) (log-obj (dom/element "Text node")) (log-obj (dom/element :li)) (log-obj (dom/element :li {:class "foo"})) (log-obj (dom/element :li {:class "bar"} "text node")) (log-obj (dom/element [:ul [:li :li :li]])) (log-obj (dom/element :ul [:li :li :li])) (log-obj (dom/element :li {} [:ul {} [:li :li :li]])) (log-obj (dom/element [:li {:class "baz"} [:li {:class "quux"}]])) (log-obj source) (log-listener-count)
要了解更多,请访问ClojureScript站点的ClojureScript资源入门。
Scala.js
Scala.js是将Scala编程语言转换为JavaScript的编译器。 Scala是一种语言,旨在将来自面向对象和函数式编程的思想融合为一种语言,以创建功能强大且易于采用的工具。
作为一种强类型语言,您可以从具有部分类型推断的灵活类型系统中获益。大多数值都可以推断,但是函数参数仍然需要显式的类型注释。
虽然支持许多常见的面向对象模式(例如,每个值都是一个对象,操作是方法调用),但是也可以获得一些函数特性,比如支持一流函数和不可变数据结构。
Scala.js的一个特殊优势是,您可以从熟悉的面向对象的方法开始,然后根据需要以自己的速度迁移到功能更强的方法,而不需要做很多工作。另外,现有的JavaScript代码和库与Scala代码兼容。
初学Scala的开发人员会发现这种语言与JavaScript并没有太大的不同。比较以下等价代码:
// JavaScript var xhr = new XMLHttpRequest(); xhr.open("GET", "https://api.twitter.com/1.1/search/" + "tweets.json?q=%23scalajs" ); xhr.onload = (e) => { if (xhr.status === 200) { var r = JSON.parse(xhr.responseText); $("#tweets").html(parseTweets(r)); } }; xhr.send();
// Scala.js val xhr = new XMLHttpRequest() xhr.open("GET", "https://api.twitter.com/1.1/search/" + "tweets.json?q=%23scalajs" ) xhr.onload = { (e: Event) => if (xhr.status == 200) { val r = JSON.parse(xhr.responseText) $("#tweets").html(parseTweets(r)) } } xhr.send()
查看scala.js“scala.js入门”文档了解更多信息。
Reason
Reason是Facebook创建和维护的一种语言,它为OCaml编译器提供了一种新的语法,代码可以翻译成JavaScript和原生代码。
作为ml家族和函数语言本身的一部分,它自然提供了一个强大而灵活的类型系统,包括推理、代数数据类型和模式匹配。它还支持不可变的数据类型和参数多态性(在其他语言中也称为泛型),但与ocaml一样,也支持面向对象编程。
使用现有的JavaScript库可以使用bucklescript绑定。您还可以在理性代码中混合使用JavaScript。插入的JavaScript代码不会被严格检查,但是对于快速修复或原型来说,它工作得很好。
如果您是react开发人员,则可以使用绑定,并且该语言还支持jsx:
/* A type variant being pattern matched */ let possiblyNullValue1 = None; let possiblyNullValue2 = Some "Hello@"; switch possiblyNullValue2 { | None => print_endline "Nothing to see here." | Some message => print_endline message }; /* Parametrized types */ type universityStudent = {gpa: float}; type response 'studentType = {status: int, student: 'studentType}; let result: response universityStudent = fetchDataFromServer (); /* A simple typed object */ type payload = Js.t {. name: string, age: int }; let obj1: payload = {"name": "John", "age": 30};
查看Reason站点的《Reason Guide入门》了解更多信息。
Haxe
Haxe是一种多范式编程语言,它的编译器可以用其他语言生成二进制文件和源代码。
虽然Haxe提供了一个支持类型推断的严格类型系统,但是如果目标语言支持它,它也可以作为动态语言工作。同样,它还支持各种编程风格,如面向对象、泛型和函数式。
当您编写Haxe代码时,您可以针对几个平台和语言进行编译,而不需要进行大量更改。还可以使用特定于目标的代码块。
您可以使用相同的代码在haxe中编写后端和前端,并使用haxe remoting实现同步和异步连接的通信。
正如所料,Haxe代码兼容现有库,但它也提供了一个成熟的标准库:
// Example extracted from http://code.haxe.org extern class Database { function new(); function getProperty<T>(property:Property<T>):T; function setProperty<T>(property:Property<T>, value:T):Void; } abstract Property<T>(String) { public inline function new(name) { this = name; } } class Main { static inline var PLAYER_NAME = new Property<String>("playerName"); static inline var PLAYER_LEVEL = new Property<Int>("playerLevel"); static function main() { var db = new Database(); var playerName = db.getProperty(PLAYER_NAME); trace(playerName.toUpperCase()); db.setProperty(PLAYER_LEVEL, 1); } }
查看haxe站点的haxe页面入门了解更多信息。
Nim
Nim是一种静态类型的多范式编程语言,具有极简主义和对空格敏感的语法,可以编译成JavaScript以及C、c++。
该语言本身非常小,但是它的元编程功能使得您可以自己实现其他语言内置的特性。它的构建块是宏、模板和泛型,使用它们可以实现从简单功能到不同范例的各种功能。本着Lisp的精神,这使得Nim成为一种非常通用的语言,可以根据您的需要进行调整。
Nim的语法抽象特性允许您根据问题调整语言,从而使真正的dsl成为可能。如果你有特殊的任务要解决,你可以得到更高的表达能力:
# Reverse a string proc reverse(s: string): string = result = "" for i in countdown(high(s), 0): result.add s[i] var str1 = "Reverse This!" echo "Reversed: ", reverse(str1) # Using templates template genType(name, fieldname: expr, fieldtype: typedesc) = type name = object fieldname: fieldtype genType(Test, foo, int) var x = Test(foo: 4566) echo(x.foo) # 4566
nim站点有一些有用的入门文档,以获取更多信息。
结论
如果JavaScript不是您最喜欢的语言,您仍然可以创建web应用程序,而不必忍受该技术的缺点。用于创建这些应用程序的选项可以满足各种各样的需求,从纯函数语言(如PureScript)到面向对象语言(如Dart)。
如果您想要比一对一语言翻译更多的东西,您可以选择Elm,它为您提供了虚拟DOM和内置体系结构等工具。
相关免费学习推荐:js视频教程
以上がJavaScript にコンパイルされる 10 の興味深い言語の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。