This article lists ten interesting languages that can be compiled into JavaScript for execution in the browser or on platforms like Node.js.
Modern applications have different requirements than simple websites. But the browser is a platform with (mostly) fixed available technologies, and JavaScript remains the core language of web applications. Any application that needs to run in a browser must be implemented in this language.
We all know that JavaScript is not the best language for every task, and when it comes to complex applications, it can fall short.
To avoid this problem, several transposers for new and existing languages have been created, all of which generate code that works in the browser without writing a single line of JavaScript, nor There are limitations to the language that need to be considered.
Dart
DART is a classic object-oriented language in which everything is an object and any object is an instance of a class ( Objects can also act as functions). It is purpose-built for building applications for browsers, servers, and mobile devices.
It is maintained by Google and is the driving language for the next generation adwords user interface. It is Google's most important revenue product, which in itself is proof of its power at scale.
The language can be converted to JavaScript for use in the browser or interpreted directly by the Dart VM, allowing server applications to be built as well. Mobile applications can be made using Flutter SDK.
Complex applications also require a mature set of libraries and language features designed specifically for the task, and Dart includes all of them. An example of a popular library is AngularDart, which is the Angular version of Dart.
It allows you to write type-safe code without too much trouble. You can write types, but you don't need to, * since they can be inferred. This allows for quick prototyping without having to think too much about the details, but once you have a working one you can add types to make it more robust.
Regarding concurrent programming in the VM, instead of using shared memory threads (Dart is single-threaded), Dart uses what they call an isolated memory heap, where communication is implemented using messages. In the browser, the situation is a little different: instead of creating a new isolation, a new worker is created.
// 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; }
For more reading, I recommend Dart’s Dart Getting Started resources.
TypeScript
TypeScript is a superset of JavaScript. A valid JavaScript program is also valid TypeScript, but with static typing added. The compiler also acts as a translator from ES2015 to the current implementation, so you always get the latest features.
Unlike many other languages, TypeScript retains the spirit of JavaScript and just adds some features to improve the robustness of the code. These are type annotations and other type-related features that make writing JavaScript more enjoyable, thanks to support for specialized tools like static analyzers and other tools to aid in the refactoring process.
In addition, adding types can improve the interface between different components of the application.
Supports type inference so you don't have to write all types from scratch. You can write a quick solution and then add all the types so you have confidence in your code.
TypeScript also supports advanced types, such as intersection types, union types, type aliases, differentiated unions, and type guards. You can view all of these in the Advanced Types page of the TypeScript Documentation site.
If you use react, you can also support jsx by adding react types:
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 is a Pure functional programming language that compiles to JavaScript, HTML and CSS. You can build an entire site using Elm, making it a great alternative to JavaScript frameworks like React.
Apps built with it automatically use a virtual DOM library, making them run very fast. A big advantage is the built-in architecture, which makes you forget about data flow and focus on data declaration and logic.
In Elm, all functions are pure functions, which means that for a given input, they always return the same output. They can't do anything unless you specify it. For example, to access a remote API, you create command functions to communicate with the outside world and subscriptions to listen for responses.
Another point of purity is that values are immutable: when you need something, you create new values, not modify them.
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视频教程
The above is the detailed content of Ten interesting languages that compile to JavaScript. For more information, please follow other related articles on the PHP Chinese website!