javascript
转译和编译_10个有趣又能编译为JavaScript的语言,你用过哪些?
點擊上方“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 = π?r2, therefore π = A/r2.// 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 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
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 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"
}
]
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 = 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)
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并沒有多大不同,對比下面兩個意思一樣的代碼:
// 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()
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 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
Get Started with Nimhttps://nim-lang.org/documentation.html
結尾
如果JavaScript不是你最喜歡的語言,你依然可以創建web應用而不用忍受這個技術的缺點。可供選擇的范圍很廣,從純粹的函數式語言,比如PureScript,到面向對象語言,比如Dart。并且如果你想要不只是語言的轉化,你也可以選擇比如Elm,Elm提供像是虛擬DOM和內置的架構這樣的工具。
你是否有嘗試了這篇文章的任何一種語言,又或者你有自己的推薦?請在評論中讓我知道!
熱門推薦:
????編寫更好的 JavaScript 條件式和匹配條件的技巧
你是否頭疼于每天有做不完的需求和改不完的bug?說說前端未來幾年的路該怎么走如何用CSS3畫出懂你的3D魔方?如有收獲,點個在看,就是對我最大的支持 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的转译和编译_10个有趣又能编译为JavaScript的语言,你用过哪些?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 奥迪安卓手机carplay(奥迪安卓)
- 下一篇: 法人章要备案吗?(法人章要备案吗)