最近讀了《CoffeeScript程序設(shè)計(jì)》的前半部分「核心 CoffeeScript」。對(duì) CoffeeScript 也是有了初步的了解庐冯,本文只是我的隨手筆記,并沒有非常系統(tǒng)的總結(jié) CoffeeScript 語法,想學(xué)習(xí)語法的同學(xué)可以看以下兩份中文材料:
為什么要用 CoffeeScript五鲫?
- 采用了 JavaScript 中的 Good Parts,符合 JS 最佳實(shí)踐
- 代碼簡(jiǎn)潔清晰岔擂,有很多語法糖
一些特性
1.有意義的空格
CoffeeScript 移除了所有的大括號(hào)和分號(hào)位喂。
JS 會(huì)自動(dòng)在行尾添加;
,但它又沒有純粹的設(shè)計(jì)為一款不需要加分號(hào)的語言乱灵,所以有時(shí)候會(huì)引起一些蛋疼的Bug塑崖。而 CoffeeScript 會(huì)在編譯出的 JS 代碼里每行都加;
,很方便痛倚。
CoffeeScript 和 Python规婆、Ruby 一樣,采用強(qiáng)制縮進(jìn)(Coffee的很多地方與 ruby 類似)蝉稳,這種簡(jiǎn)潔抒蚜,可讀性又很強(qiáng)的代碼,讓人大愛颠区。
2.變量作用域的控制
JS 中的變量作用域一直讓人詬病削锰。
CoffeeScript 把編譯生成的 JS 封裝在一個(gè)匿名函數(shù)中:
(function(){
// 這里是編譯生成的代碼
}).call(this);
這樣就巧妙避免了全局作用域的污染。同時(shí)毕莱,CoffeeScript 始終在編譯生成的 JS 代碼中用 var
聲明變量器贩。
3.存在性判斷
CoffeeScript 中有個(gè)操作符 ?
,用于檢測(cè)變量是否存在朋截。
console.log html if html?
這句 CoffeeScript 編譯過來為(去掉了匿名封裝函數(shù)蛹稍,為了方便,之后的編譯后代碼都去掉)
if (typeof html !== "undefined" && html !== null) {
console.log(html);
}
可見部服,?
會(huì)先檢測(cè)變量有沒有定義唆姐,如果定義了再檢測(cè)是否為 null。
4.函數(shù)和 splat 操作符
CoffeeScript 中去掉了 function
關(guān)鍵字廓八。用 () ->
定義一個(gè)函數(shù)奉芦。括號(hào)內(nèi)為參數(shù)赵抢,可以為參數(shù)設(shè)置默認(rèn)值。如:
myFunction = (a, b = 2) ->
a + b
編譯為:
var myFunction;
myFunction = function(a, b) {
if (b == null) {
b = 2;
}
return a + b;
};
調(diào)用函數(shù)的時(shí)候声功,還可以不用括號(hào)烦却。如:
myFunction 3, 5
有一點(diǎn)需要注意一下,CoffeeScript 會(huì)在編譯后的 JS 代碼中自動(dòng)為最后一行添加 return
關(guān)鍵字先巴。所以不論函數(shù)的最后一行是什么其爵,都會(huì)成為返回值。如果你不想讓最后一行成為返回值伸蚯,就需要另起一行自己加上 return
摩渺。
splat 操作符非常強(qiáng)大。在你的函數(shù)需要接受可變數(shù)量的參數(shù)時(shí)就需要它了剂邮。書上的栗子:
splatter = (etc...) ->
console.log "Length: #{etc.length}, Values: #{etc.join(', ')}"
// CoffeeScript 中字符串插值用 #{}
splatter()
splatter("a", "b", "c")
// 輸出
Length: 0, Values:
Length: 3, Values: a, b, c
就在某個(gè)參數(shù)后面加上...
摇幻,就使傳入的參數(shù)自動(dòng)轉(zhuǎn)化為一個(gè)數(shù)組。splat 操作符可以出現(xiàn)在參數(shù)列表的任意位置挥萌,但是參數(shù)列表中只能有一個(gè) splat 操作符囚企。
5.數(shù)組與區(qū)間
一般定義數(shù)組是這樣:
myArray = ["a", "b", "c"]
在 CoffeeScript 里你還可以這樣:
myArray = [
"a"
"b"
"c"
]
- 在 JS 中判斷是否存在于數(shù)組,需要用
Array.prototype.indexOf
瑞眼,在 CoffeeScript 中只需要用in
:
console.log "d was not be found" unless "d" in myArray
// 輸出
d was not be found
- 交換賦值
x = "X"
y = "Y"
[x, y] = [y, x]
交換 x龙宏、y 的值就這么簡(jiǎn)單!
- 多重賦值
myArray = ["A", "B", "C", "D"]
[start, middle..., end] = myArray // 可配合 splat 操作符使用
console.log "start: #{start}"
console.log "middle: #{middle}"
console.log "end: #{end}"
// 輸出
start: A
middle: B,C
end: D
- 區(qū)間
區(qū)間能讓定義包含兩個(gè)數(shù)字之間所有數(shù)字的數(shù)組變得很容易伤疙。
myRange = [1..10]
console.log myRange
// 輸出 [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
如果不想包括結(jié)束數(shù)值银酗,可以用 ...
代替 ..
。
myRange = [10...1]
console.log myRange
// 輸出 [ 10, 9, 8, 7, 6, 5, 4, 3, 2 ]
常見的數(shù)組操作徒像,都可以通過區(qū)間完成:
myArray = [1..10]
// 分割數(shù)組
part = myArray[0..2]
console.log part
// 輸出 [ 1, 2, 3 ]
// 替換數(shù)組值
myArray = [1..10]
myArray[4..7] = ["a", "b", "c", "d"]
console.log myArray
// 輸出 [ 1, 2, 3, 4, 'a', 'b', 'c', 'd', 9, 10 ]
// 插入值
myArray = [1..10]
myArray[4..-1] = ["a", "b", "c", "d"]
console.log myArray
// 輸出 [ 1, 2, 3, 4, 'a', 'b', 'c', 'd', 5, 6, 7, 8, 9, 10 ]
6.類和繼承
一例勝千言:
class Animal
constructor: (@name) ->
move: (meters) ->
alert @name + " moved #{meters}m."
class Snake extends Animal
move: ->
alert "Slithering..."
super 5
class Horse extends Animal
move: ->
alert "Galloping..."
super 45
sam = new Snake "Sammy the Python"
tom = new Horse "Tommy the Palomino"
sam.move()
tom.move()
這是官網(wǎng)的例子黍特,麻麻再也不用擔(dān)心我在 JS 里使用類和繼承了 T_T。
- consturctor 函數(shù)為類的構(gòu)造函數(shù)锯蛀。在
new
的時(shí)候調(diào)用灭衷,可以重寫它。 -
::
就和 JS 里的prototype
一樣
很多語法糖
我對(duì)「語法糖」的理解就是讓代碼的讀寫更簡(jiǎn)單旁涤。
CoffeeScript 中添加了一些關(guān)鍵字翔曲,如 unless when then until do
等。不僅如此劈愚,CoffeeScript 引入了很多別名來代替一些關(guān)鍵字:
別名 | 對(duì)應(yīng)關(guān)鍵字 | ||
---|---|---|---|
is | === | ||
isnt | !== | ||
not | ! | ||
and | && | ||
or | |||
true, yes, on | true | ||
false, no, off | false | ||
@, this | this | ||
of | in | ||
in | no JS equivalent |
運(yùn)用別名和新關(guān)鍵字瞳遍,使代碼讀起來就和普通的英文一樣。而且 CoffeeScript 還自動(dòng)為你添加關(guān)鍵字菌羽,如函數(shù)最后的 return
掠械,switch
后自動(dòng)添加 break
(這種符合我們惰性的改進(jìn)都是偉大的!ヽ( ?)?)。
安裝及用法
1.安裝:
npm install -g coffee-script
2.用法:
安裝完成后猾蒂,直接在命令行中輸入 coffee
均唉,就進(jìn)入了 CoffeeScript 的 REPL(Read-eval-print-loop) 模式,這是一個(gè)可交互的控制臺(tái)肚菠,你可以輸入 CoffeeScript 代碼立即執(zhí)行浸卦。如圖:
也可以用指令編譯 CoffeeScript 代碼執(zhí)行(CoffeeScript 代碼文件后綴名為 coffee):
coffee -c hello_world.coffee
還有一些其他選項(xiàng),我目前用的最多的是 -o
案糙、-p
、-w
這三個(gè)靴庆。
-o
即 --output
时捌,設(shè)置編譯后 JS 文件輸出到指定文件夾
-p
即 --print
,直接在終端打印出編譯后的 JS 代碼
-w
即 --watch
炉抒,監(jiān)視文件改變奢讨,一有變化就重新執(zhí)行這條指令
coffee -c hello_world.coffee -o ./js -w
搭配起來就可以邊寫邊編譯到指定文件夾。
其他
有篇文章《CoffeeScript: The beautiful way to write JavaScript》焰薄,對(duì) JS 和 CoffeeScript 的論述很中肯拿诸。但文中對(duì)「什么才是優(yōu)美的代碼」的總結(jié)更讓人印象深刻:
- beautiful code uses the least amount of code to solve a given problem
- beautiful code is readable and understandable
- beautiful code is achieved not when there is nothing more to add, but when there is nothing left to take away (just like great designs)
- the minimal length is a side-effect of beautiful code and not a goal or a measure
參考文獻(xiàn)
原文地址:CoffeeScript 筆記
本作品采用知識(shí)共享 署名-非商業(yè)性使用-禁止演繹 4.0 國(guó)際 許可協(xié)議進(jìn)行許可。