源代碼下載:?learnLivescript.ls
LiveScript 是一種具有函數(shù)式特性且編譯成 JavaScript 的語言,能對應(yīng) JavaScript 的基本語法。 還有些額外的特性如:柯里化,組合函數(shù),模式匹配,還有借鏡于 Haskell,F(xiàn)# 和 Scala 的許多特點(diǎn)。
LiveScript 誕生于?Coco,而 Coco 誕生于?CoffeeScript。 LiveScript 目前已釋出穩(wěn)定版本,開發(fā)中的新版本將會加入更多特性。
非常期待您的反饋,你可以通過?@kurisuwhyte?與我連系 :)
# 與 CoffeeScript 一樣,LiveScript 使用 # 單行注解。
/*
多行注解與 C 相同。使用注解可以避免被當(dāng)成 JavaScript 輸出。
*/
# 語法的部份,LiveScript 使用縮進(jìn)取代 {} 來定義區(qū)塊,
# 使用空白取代 () 來執(zhí)行函數(shù)。
########################################################################
## 1\. 值類型
########################################################################
# `void` 取代 `undefined` 表示未定義的值
void # 與 `undefined` 等價但更安全(不會被覆寫)
# 空值則表示成 Null。
null
# 最基本的值類型數(shù)據(jù)是羅輯類型:
true
false
# 羅輯類型的一些別名,等價于前者:
on; off
yes; no
# 數(shù)字與 JS 一樣,使用倍精度浮點(diǎn)數(shù)表示。
10
0.4 # 開頭的 0 是必要的
# 可以使用底線及單位后綴提高可讀性,編譯器會自動略過底線及單位后綴。
12_344km
# 字串與 JS 一樣,是一種不可變的字元序列:
"Christina" # 單引號也可以!
"""Multi-line
strings
are
okay
too."""
# 在前面加上 \ 符號也可以表示字串:
\keyword # => 'keyword'
# 數(shù)組是值的有序集合。
fruits =
* \apple
* \orange
* \pear
# 可以用 [] 簡潔地表示數(shù)組:
fruits = [ \apple, \orange, \pear ]
# 你可以更方便地建立字串?dāng)?shù)組,并使用空白區(qū)隔元素。
fruits = <[ apple orange pear ]>
# 以 0 為起始值的數(shù)組下標(biāo)獲取元素:
fruits[0] # => "apple"
# 對象是無序鍵值對集合(更多給節(jié)將在下面章節(jié)討論)。
person =
name: "Christina"
likes:
* "kittens"
* "and other cute stuff"
# 你也可以用更簡潔的方式表示對象:
person = {name: "Christina", likes: ["kittens", "and other cute stuff"]}
# 可以通過鍵值獲取值:
person.name # => "Christina"
person["name"] # => "Christina"
# 正則表達(dá)式的使用跟 JavaScript 一樣:
trailing-space = /\s$/ # dashed-words 變成 dashedWords
# 你也可以用多行描述表達(dá)式!(注解和空白會被忽略)
funRE = //
function\s+(.+) # name
\s* \((.*)\) \s* # arguments
{ (.*) } # body
//
########################################################################
## 2\. 基本運(yùn)算
########################################################################
# 數(shù)值操作符與 JavaScript 一樣:
1 + 2 # => 3
2 - 1 # => 1
2 * 3 # => 6
4 / 2 # => 2
3 % 2 # => 1
# 比較操作符大部份也一樣,除了 `==` 等價于 JS 中的 `===`,
# JS 中的 `==` 在 LiveScript 里等價于 `~=`,
# `===` 能進(jìn)行對象、數(shù)組和嚴(yán)格比較。
2 == 2 # => true
2 == "2" # => false
2 ~= "2" # => true
2 === "2" # => false
[1,2,3] == [1,2,3] # => false
[1,2,3] === [1,2,3] # => true
+0 == -0 # => true
+0 === -0 # => false
# 其它關(guān)系操作符包括 <、<=、> 和 >=
# 羅輯值可以通過 `or`、`and` 和 `not` 結(jié)合:
true and false # => false
false or true # => true
not false # => true
# 集合也有一些便利的操作符
[1, 2] ++ [3, 4] # => [1, 2, 3, 4]
'a' in <[ a b c ]> # => true
'name' of { name: 'Chris' } # => true
########################################################################
## 3\. 函數(shù)
########################################################################
# 因?yàn)?LiveScript 是函數(shù)式特性的語言,你可以期待函數(shù)在語言里被高規(guī)格的對待。
add = (left, right) -> left + right
add 1, 2 # => 3
# 加上 ! 防止函數(shù)執(zhí)行后的返回值
two = -> 2
two!
# LiveScript 與 JavaScript 一樣使用函式作用域,且一樣擁有閉包的特性。
# 與 JavaScript 不同的地方在于,`=` 變量賦值時,左邊的對象永遠(yuǎn)不用變量宣告。
# `:=` 操作符允許*重新賦值*父作用域里的變量。
# 你可以解構(gòu)函數(shù)的參數(shù),從不定長度的參數(shù)結(jié)構(gòu)里獲取感興趣的值。
tail = ([head, ...rest]) -> rest
tail [1, 2, 3] # => [2, 3]
# 你也可以使用一元或二元操作符轉(zhuǎn)換參數(shù)。當(dāng)然也可以預(yù)設(shè)傳入的參數(shù)值。
foo = (a = 1, b = 2) -> a + b
foo! # => 3
# 你可以以拷貝的方式傳入?yún)?shù)來避免副作用,例如:
copy = (^^target, source) ->
for k,v of source => target[k] = v
target
a = { a: 1 }
copy a, { b: 2 } # => { a: 1, b: 2 }
a # => { a: 1 }
# 使用長箭號取代短箭號來柯里化一個函數(shù):
add = (left, right) --> left + right
add1 = add 1
add1 2 # => 3
# 函式里有一個隱式的 `it` 變量,意謂著你不用宣告它。
identity = -> it
identity 1 # => 1
# 操作符在 LiveScript 里不是一個函數(shù),但你可以簡單地將它們轉(zhuǎn)換成函數(shù)!
# Enter the operator sectioning:
divide-by-2 = (/ 2)
[2, 4, 8, 16].map(divide-by-2) .reduce (+)
# LiveScript 里不只有應(yīng)用函數(shù),如同其它良好的函數(shù)式語言,你可以合并函數(shù)獲得更多發(fā)揮:
double-minus-one = (- 1) . (* 2)
# 除了普通的數(shù)學(xué)公式合并 `f . g` 之外,還有 `>>` 和 `<<` 操作符定義函數(shù)的合并順序。
double-minus-one = (* 2) >> (- 1)
double-minus-one = (- 1) << (* 2)
# 說到合并函數(shù)的參數(shù), LiveScript 使用 `|>` 和 `<|` 操作符將參數(shù)傳入:
map = (f, xs) --> xs.map f
[1 2 3] |> map (* 2) # => [2 4 6]
# 你也可以選擇填入值的位置,只需要使用底線 _ 標(biāo)記:
reduce = (f, xs, initial) --> xs.reduce f, initial
[1 2 3] |> reduce (+), _, 0 # => 6
# 你也能使 _ 讓任何函數(shù)變成偏函數(shù)應(yīng)用:
div = (left, right) -> left / right
div-by-2 = div _, 2
div-by-2 4 # => 2
# 最后,也很重要的,LiveScript 擁有後呼叫特性, 可以是基於回調(diào)的代碼
# (你可以試試其它函數(shù)式特性的解法,比如 Promises):
readFile = (name, f) -> f name
a <- readFile 'foo'
b <- readFile 'bar'
console.log a + b
# 等同於:
readFile 'foo', (a) -> readFile 'bar', (b) -> console.log a + b
########################################################################
## 4\. 模式、判斷和流程控制
########################################################################
# 流程控制可以使用 `if...else` 表達(dá)式:
x = if n > 0 then \positive else \negative
# 除了 `then` 你也可以使用 `=>`
x = if n > 0 => \positive
else \negative
# 過於復(fù)雜的流程可以用 `switch` 表達(dá)式代替:
y = {}
x = switch
| (typeof y) is \number => \number
| (typeof y) is \string => \string
| 'length' of y => \array
| otherwise => \object # `otherwise` 和 `_` 是等價的。
# 函數(shù)主體、宣告式和賦值式可以表式成 `switch`,這可以省去一些代碼:
take = (n, [x, ...xs]) -->
| n == 0 => []
| _ => [x] ++ take (n - 1), xs
########################################################################
## 5\. 推導(dǎo)式
########################################################################
# 在 JavaScript 的標(biāo)準(zhǔn)函式庫里有一些輔助函數(shù)能幫助處理列表及對象
#(LiveScript 則帶有一個 prelude.ls ,作為標(biāo)準(zhǔn)函式庫的補(bǔ)充 ),
# 推導(dǎo)式能讓你使用優(yōu)雅的語法且快速地處理這些事:
oneToTwenty = [1 to 20]
evens = [x for x in oneToTwenty when x % 2 == 0]
# 在推導(dǎo)式里 `when` 和 `unless` 可以當(dāng)成過濾器使用。
# 對象推導(dǎo)式在使用上也是同樣的方式,差別在于你使用的是對象而不是數(shù)組:
copy = { [k, v] for k, v of source }
########################################################################
## 6\. OOP
########################################################################
# 雖然 LiveScript 是一門函數(shù)式語言,但具有一些命令式及面向?qū)ο蟮奶匦浴?# 像是 class 語法和一些借鏡於 CoffeeScript 的類別繼承語法糖:
class Animal
(@name, kind) ->
@kind = kind
action: (what) -> "*#{@name} (a #{@kind}) #{what}*"
class Cat extends Animal
(@name) -> super @name, 'cat'
purr: -> @action 'purrs'
kitten = new Cat 'Mei'
kitten.purr! # => "*Mei (a cat) purrs*"
# 除了類別的單一繼承模式之外,還提供了像混入 (Mixins) 這種特性。
# Mixins 在語言里被當(dāng)成普通對象:
Huggable =
hug: -> @action 'is hugged'
class SnugglyCat extends Cat implements Huggable
kitten = new SnugglyCat 'Purr'
kitten.hug! # => "*Mei (a cat) is hugged*"
LiveScript 還有許多強(qiáng)大之處,但這些應(yīng)該足夠啟發(fā)你寫些小型函數(shù)式程式了。?LiveScript有更多關(guān)于 LiveScript 的資訊 和線上編譯器等著你來試!
你也可以參考?prelude.ls,和一些?#livescript
?的網(wǎng)絡(luò)聊天室頻道。
更多建議: