点击上方“IT平头哥联盟”,选择“置顶或者星标”

你的关注意义重大!

来源:https://www.sitepoint.com/

现代应用相比普通的网页有不同的要求。但是浏览器是一个有着一套(大部分)固定可用的技术的平台,JavaScript依然是web应用的核心语言;任何需要在浏览器上跑的应用都需要使用这种语言。

我们都知道Javascript并不是最好的语言,特别是在复杂的应用中,它可能不太能胜任。为了避免这种情况,一些新的语言或现有语言的编译器被创造出来,你不用写一行Javascript或者考虑这种语言的局限,就能生产在浏览器能运行的代码。

这篇文章包括了十种有趣的语言能够编译为Javascript,在浏览器或者Node.js中被执行。

--ADVERTISEMENT--

Dart

Dart是一个典型的面向对象的语言,任何东西都是一个对象并且任何对象都是一个类的实例(对象也可以表现为函数)。它的特殊性用于打造面向浏览器,服务器和移动设备的应用。它由谷歌来维护,是用于驱动下一代的AdWords UI。AdWords UI是谷歌盈利的重要产品,这也证明了它在体量上的强大。

这种语言可以编译为JavaScript用于浏览器,或者直接通过Dart VM解释,这样也可以允许你构建服务端应用。移动应用可以通过Flutter SDK创建。

复杂的应用还需要一系列特别为任务所设计的成熟的库和语言特性,Dart这些都有。举例来说一个流行的库是AngularDart,一个Dart版本的Angular。

它允许你写非侵入式的类型安全的代码,但是这不是必须的,因为他们可以自动检测类型。它可以允许你快速构建原型而不用过于思考细节,一旦你需要的时候,你可以加入类型让它更健壮。

至于在VM中的并发编程,相比与共享内存线程(Dart是单线程的),Dart使用所谓的_Isolates_,有它自己的堆内存,而交流是通过传递信息。在浏览器上,情况就有点不一样了:相比与创建一个新的_isolates_,你创建一个新的_Workers_。

// 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 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 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;}

Get started with Dart https://www.dartlang.org/guides/get-started

TypeScript

TypeScript 是Javascript的超集;一个有效的Javascript项目也是一个有效的TypeScript项目只是添加了静态类型。编译器也可以作为ES2015+到当前实现的转译器,这样你总是能得到最新的特性。

不同于其他语言,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是一个可以编译成JS,HTML和JS的纯函数式编程语言。你可以只通过Elm创建一个完整的网站,这使得它是一个对像React这样的Javascript框架的一个很好的代替。通过它创建的应用自动使用了虚拟DOM库,使得它很快。一个大的加分项是内建的结构让你忘记数据流而是关注于数据声明和逻辑。

在Elm中,所有函数都是纯粹的,这意味着他们总是对一个给予的输入返回一个相同的输出。T他们不能做其他任何事情,除非你指定。举例来说,获取一个远程的API你会创建一个_command_函数来通讯外部世界,和一个 subscriptions 函数监听回复。另一个纯粹的点是,值是不可变的,当你需要什么的时候,你创建一个新值而不是改变它。

ELm的接受可以是平缓的;可以使用_ports_来和Javascript或其他库沟通。虽然Elm还没有到达版本1,它已经用于复杂大型的应用了,这使得它对复杂应用是一个可行的解决方案。

ELm其中一个吸引人的功能是初学者友好的编译器,它生成帮助你修复你的代码的信息,而不是产生难以阅读的信息。如果你正在学习这门语言,编译器本身就是一个大的帮助。

module Main exposing (..)

import Html exposing (..)

-- MAIN

main : Program Never Model Msgmain =    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 Msgview model =    div [] [text model]

-- SUBSCRIPTIONS

subscriptions : Model -> Sub Msgsubscriptions model =    Sub.none

Get Started with Elm:https://www.sitepoint.com/functional-reactive-programming-elm-introduction/

PureScript

PureScript 是一个纯函数强类型的编程语言,由Phil Freeman创造。它旨在与现有的JavaScript库进行很好的兼容,与Haskell精神上类似,但是核心保留了Javascript。

PureScript一个重要的点是它的极简主义。它没有包含任何在其他语言认为很重要的功能库。比如,相比于在编译器中包含generators和promises,你可以自己使用指定的库来完成这个任务。你可以选择你想要的功能的实现,当使用PureScript的时候需要高效和个性化的经验,能使生成的代码尽可能的小。

这个编译器另一个重要的功能是构建出清晰可读的代码,能够兼容Javascript包括库和工具。

和其他语言一样,PureScript有它自己的构建工具称为Pulp,可以和Gulp做对比,只是用这个语言写的。

至于类型系统,不同于另一个ML类的语言Elm,PureScript支持更先进的类型特性比如高级类类型和类型类,这些是从Haskell来的特性,允许创建复杂的抽象。

module Main where

import Preludeimport 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"        }      ]

Get Started with PureScripthttps://github.com/purescript/documentation/blob/master/guides/Getting-Started.md

CoffeeScript

CoffeeScript是一个旨在暴露JavaScript的精华并提供一个干净的语法并在合适地方保留语义的语言。虽然近年来这个语言的热度在下降,它正在改变方向并且现在有一个新的大版本支持ES2015+特性。

你用CoffeeScript写的代码直接转化为可读的Javascript代码并且兼容现有的库。从2版本开始,编译器会产生兼容最新版本的ECMAScript的代码,比如,每次你使用class,你就在Javascript中得到class。并且,如果你使用React,好消息是,JSX兼容CoffeeScript。

这个编译器有一个十分有特色的功能是有能力处理用literate style写的代码。literate style相比于强调代码而把注释作为添加这种方式,而是你需要在一开始就写注释,代码只是偶尔出现。这种写代码的方式由Donald Knuth推荐,使得一个代码文件非常像一个技术文档。

相比于其他语言,CoffeeScript代码可以在浏览器中用一个库直接执行。所以如果你想要写一个快速测试,你可以写你的代码在一个text/coffeescriptscript标签中,并且引入编译器,这样就可以把你的代码轻易的转化为JavaScript了。

# Assignment:number   = 42opposite = 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)

Get Started with CoffeeScript http://coffeescript.org/v2/#coffeescript-2

ClojureScript

ClojureScript是一个转化Clojure编程语言为JavaScript的编译器。Clojure是一个多用途的函数式原因伴随着动态类型和不可变数据结构的支持。

这是这个列表中唯一一个属于Lisp家族的语言,自然有着它们共同的特性。举例来说,代码可以作为数据,支持宏系统,使得元编程成为可能。Unlike other Lisps, Clojure has support for immutable data structures, making the management of side-effects easier.不同于其他类Lisp,Clojure支持不可变数据结构,使得函数副作用的管理更容易。

这个语法对初学者看起吓人,因为圆括号的使用。但这样使用是经过深思熟虑的,并且在长远看来你一定会感谢这种语法的。语法的极简和抽象能力使得Lisp成为一个解决高抽象问题的强力工具。

虽然Clojure主要是一个函数式语言,但是不像PureScript或者Elm那样纯粹。函数副作用还是会发生,但是其他函数式特性也会存在。

ClojureScript使用Google Closure做代码优化并且也兼容现有的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 destinatione))))(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)

Get Started with ClojureScript https://clojurescript.org/guides/quick-start

Scala.js

Scala.js是一个将Scala编程语言转化为JavaScript的编译器。Scala是一个旨在融合面向对象和函数式编程两种思想到一种语言,为了打造容易接受的强力的工具

作为一个强类型语言,你会从它部分类型推断这种灵活的类型系统中受益。大部分的值会被推断,但函数参数仍然需要明确的类型注释。

虽然许多通常的面向对象模式都支持(比如任何值都是一个对象并且操作是一个方法调用),但你也有函数式特性比如一等函数和不可变数据结构。

Scala.js其中一个特殊的优势是,你可以毫不费力的从你熟悉的面向对象开始向更函数式的转移,以你自己的需要和步调。同样的,现存的JavaScript代码和库和你的Scala代码兼容。

Scala的初学者会发现这个语言和JavaScript并没有多大不同,对比下面两个意思一样的代码:

// JavaScriptvar 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.jsval 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()

Get Started with Scala.jshttps://www.scala-js.org/tutorial/basic/

Reason

Reason是一个由Facebook创造和维护的语言,它为OCaml编译器提供了新的语法,并且代码可以转换成JavaScript和原生代码。

作为ML家族的一部分并且自己本身是函数式语言,它天生提供了强大但是灵活的伴随类型推断的类型系统,代数数据类型和模式匹配。它也支持不可变数据类型和参数多态(也被其他语言称为泛型),但是在OCaml中,也是支持面向对象编程的。

通过 bucklescript绑定就可以使用现存的JavaScript库。你也可以在你的Reason代码旁边混入你的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};

Get Started with Reason https://reasonml.github.io/guide/javascript/quickstart

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;function setProperty<T>(property:Property, 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("playerLevel");static function main() {var db = new Database();var playerName = db.getProperty(PLAYER_NAME);    trace(playerName.toUpperCase());    db.setProperty(PLAYER_LEVEL, 1);  }}

Get Started with Reasonhttps://haxe.org/documentation/introduction/language-introduction.html

Nim

Nim是一个静态类型,多范式编程语言,有着极简风格与空格敏感的语法,编译为C,C++和JavaScript。

这个语言本身很小,但它的元编程能力会吸引你自己去实现一些在别的语言内置的功能。这些构建模块有宏,模板和泛型,通过它们你可以实现不论是简单的功能还是不同的泛型。这使得Nim成为一个非常通用的语言可以适应你的需求,有着Lisp的精髓。

Nim的语法抽象功能允许你去让语言去适应你的功能,让真正的[DSLs][20]成为可能。如果你有着专门的任务需要处理,你可以获得更高级的表达性。

# Reverse a stringproc 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 templatestemplate genType(name, fieldname: expr, fieldtype: typedesc) =  type    name = object      fieldname: fieldtype

genType(Test, foo, int)

var x = Test(foo: 4566)echo(x.foo) # 4566

Get Started with Nimhttps://nim-lang.org/documentation.html

结尾

如果JavaScript不是你最喜欢的语言,你依然可以创建web应用而不用忍受这个技术的缺点。可供选择的范围很广,从纯粹的函数式语言,比如PureScript,到面向对象语言,比如Dart。并且如果你想要不只是语言的转化,你也可以选择比如Elm,Elm提供像是虚拟DOM和内置的架构这样的工具。

你是否有尝试了这篇文章的任何一种语言,又或者你有自己的推荐?请在评论中让我知道

热门推荐:

编写更好的 JavaScript 条件式和匹配条件的技巧

你是否头疼于每天有做不完的需求和改不完的bug?说说前端未来几年的路该怎么走如何用CSS3画出懂你的3D魔方?如有收获,点个在看,就是对我最大的支持

转译和编译_10个有趣又能编译为JavaScript的语言,你用过哪些?相关推荐

  1. 使用Java编一个有意思的_一个有趣的Java编译问题

    学员冯伟立今天中午问了我一个有趣的Java编译问题,我也无法给他解释,不知道有没有路过的高人能够解释清楚原因,望不吝赐教! 下面程序的main方法中的第二行代码和注释中的两行代码表达的意思完全相同,注 ...

  2. mysql 5.7 源码编译安装_mysql-5.7.*源码编译安装

    mysql-5.7.*源码编译安装 系统安装条件 官方文档说明:http://dev.mysql.com/doc/refman/5.7/en/source-installation.html 1> ...

  3. 分享2011年10月网上随机搜集的超酷超有趣的web开发和Javascript代码

    日期:2011/10/26       来源:jquery4u.com    编译:GBin1.com 2011年10月份就快结束了,web开发世界也发生了很多有趣的事情.下面是GBin1编译的201 ...

  4. VC 工程中包含 .c 或cpp文件编译时产生的.pch预编译头错误(C1853)

    编写混合  时出现这样错误"fatal error C1853: "Debug\SMS_Test.pch"预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 ...

  5. linux编译动态库未定义,linux 编译动态链接库 so,避免运行时才发现函数未 ......

    ldd  查看 elf文件依赖的  so 动态链接库 可以  export LD_LIBRARY_PATH=/path 设置 so文件的路径, nm  -u  *.so  或者 nm |grep  U ...

  6. 【Android 插件化】VirtualAppEx 编译运行 ( VirtualAppEx 简介 | 配置 VirtualAppEx 编译环境 | 编译运行 VirtualAppEx 代码 )

    文章目录 一.VirtualAppEx 简介 二.配置 VirtualAppEx 编译环境 1.Android Studio 3.0 2.NDK 版本 ( Android NDK r10e ) 3.配 ...

  7. Android编译系统分析三:make完整编译android系统

    这篇博客的目标是摸清楚默认编译整个android系统时代码的流程. 当我们执行make的时候,会查找当前的Makefie文件或者makefile文件并且执行,在android顶级源码目录下面,确实有个 ...

  8. Jar包反编译后修改源码再编译

    Jar包反编译后修改源码再编译 文章目录 Jar包反编译后修改源码再编译 1. 场景 2. 详细步骤 2.1 查看源码 2.2 生成源文件 2.3 构建项目 2.4 编译成jar包 3. 参考链接 1 ...

  9. qt5.5 静态编译 mysql_QT5.3.2+mingw静态编译(生成exe大约14M)

    在网上找了很久的QT静态编译方法,基本参考:http://www.baidu.com/link?url=3JiyMFpMziH5Qdw73NVnTg1wPb6JT9LywvOzCE6FAOE-LrtE ...

最新文章

  1. 点分治 + 树状数组 ---- E. Close Vertices(点分治 + 二维数点)
  2. 获取图像的梯度,方向和方向梯度图像
  3. java学习笔记(2):获取文件名和自定义文件过滤器
  4. 减少过程中的浪费(2/2)
  5. TimesTen Warnings and Errors - TT0400 to TT9999 [IDnbsp (
  6. css设置a连接禁用样式_使用CSS禁用链接
  7. 8X25Q充电部分软件梳理(CP侧)
  8. 清理垃圾代码bat_电脑一键清理垃圾图文详解
  9. malloc函数的使用以及内存泄露情况
  10. linux未被识别crond服务,linux 定时任务 crond 服务介绍
  11. 囚徒困境、价格大战与 iPhone 的价格
  12. C# 判断程序是否已经在运行
  13. CSS3 详细新增内容
  14. linux系统时间和硬件时钟问题
  15. webstorm使用指南
  16. 华为收入超过阿里腾讯总和!等等,先把鸿蒙说清楚!
  17. 国外物联网平台大盘点
  18. 油溶性球形金纳米颗粒,CAS7440-57-5
  19. 交通运输大数据发展特点、政策、应用及趋势 | 交通运输部科学研究院黄莉莉
  20. 将一根木棍分成三段,求这三段构成三角形的概率 和  在一圆周上任意取三个点构成锐角三角形的概率是多少

热门文章

  1. Java命令行界面(第22部分):argparser
  2. arrays.sort(._Arrays.sort与Arrays.parallelSort
  3. 提升您的Hibernate引擎
  4. Hazelcast入门指南第4部分
  5. EJB 3.x:生命周期和并发模型(第1部分)
  6. 什么是Mockito Extra接口?
  7. Java DB嵌入式模式
  8. JavaFX:太空侵略者在175 LOC以下
  9. Maven不会吮吸。 。 。 但是Maven文件会
  10. macOS安装Maven_IDEA集成Maven