
今天和大家介紹一個有趣的東西....
介紹
CoffeeScript 是一門編譯到 JavaScript 的小巧語言. 在 Java 般笨拙的外表下, JavaScript 其實有著一顆華麗的心臟. CoffeeScript 嘗試用簡潔的方式展示 JavaScript 優(yōu)秀的部分.
CoffeeScript 是一門簡潔的,構(gòu)架于JavaScript之上的預(yù)處理器語言,可以靜態(tài)編譯成JavaScript,語法主要受ruby和python影響。
優(yōu)點&&安裝
- 更少,更緊湊,和更清晰的代碼
- 通過規(guī)避和改變對JavaScript中不良部分的使用,只留下精華,讓代碼減少出錯率,更容易維護
- 在很多常用模式的實現(xiàn)上采用了JavaScript中的最佳實踐
- CoffeeScript生成的JavaScript代碼都可以完全通過JSLint的檢測
安裝
最簡單的安裝和測試CoffeeScript的方法,是使用node.js的npm安裝,然后使用命令行腳本實時編譯
npm install -g coffee-script
coffee -w --output lib --compile src
什么情況下不推薦使用CoffeeScript?
CoffeeScript不是JavaScript的超集,也不是完全替代品,不應(yīng)該在不會JavaScript的情況下使用CoffeeScript工作。
CoffeeScript是一種需要預(yù)編譯的語言,不能在運行時(Runtime)解釋,這造成了她普遍被人質(zhì)疑的一點,就是如果代碼中出現(xiàn)運行時錯誤時難以調(diào)試,不過從實際使用上來看,因為CoffeeScript的編譯結(jié)果大部分情況下自然而合理。
這種靜態(tài)編譯還有一個額外的好處,就是CoffeeScript和現(xiàn)有的環(huán)境(瀏覽器,Node,Rhino等)與庫完全兼容
簡單介紹入門
注釋:
在coffeeScript中,注釋均采用 # 符號
# single line comment
###
multi line comment
###
關(guān)于語句后加 ; 的問題
在js中,如果認(rèn)為當(dāng)前語句和隨后語句是一個整體的話,就不會自己加;,比如以下javascript代碼
//javascript code
var y = x+f
(a+b).toString()
//parsed to:
var y = x+f(a+b).toString();
---CoffeeScript在編譯時為每條語句加上;,因此在代碼中不需要寫;
作用域
在js中最糟糕的設(shè)計就是全局變量,當(dāng)你忘記用var聲明變量的時候,這個變量會成為全局對象上的一個屬性
CoffeeScript避免了這點
輸入:foo = "bar"
編譯后:
(function() {
var foo;
foo = "bar";
}).call(this);
任何的代碼都會使用Immediate Function包裝,這樣foo成為了本地變量,并且,可以通過call指定的this引用全局對象
為了方便起見,之后的編譯后代碼描述不會再加上這個包裝
實際上在CoffeeScript中,你也不需要再用var聲明變量,編譯后會自動加上var,并且將聲明hoisting,即放到作用域的頂部,看一個來自官方文檔的例子
輸入:
outer = 1
change = ->
inner = -1
outer = 10
inner = change()
->是函數(shù)定義的簡寫方式,之后我們會探討(當(dāng)時使用的是ES2015還未有ES6的剪頭語法)
編譯后:
var change, inner, outer;
outer = 1;
change = function() {
var inner;
inner = -1;
return outer = 10;
};
inner = change();
賦值
首先是字符串可以用類ruby的語法內(nèi)嵌
target = "world"
alert "hello, #{target}"
其次是字面量,可以用類似YAML的方法定義對象字面量
object1 = one: 1, two: 2
object2 =
one: 1
two: 2
class: "numbers"
注意保留字class,現(xiàn)在可以直接作為對象的key了
數(shù)組也可以分行
arr = [
1
2
]
數(shù)組
數(shù)組的操作引入了來自ruby的Range概念,并且可以將字符串完全作為數(shù)組操作
numbers = [0..9]
numbers[3..5] = [-3, -4, -5]
my = "my string"[0..1]
判斷一個值是否在數(shù)組內(nèi),在js中可以用Array.prototype.indexOf,不過IE8及以下不支持,CoffeeScript提供了跨瀏覽器的in操作符解決
arr = ["foo", "bar"]
"foo" in arr
編譯后:
var arr,
__indexOf = [].indexOf || function(item) {
for (var i = 0, l = this.length; i < l; i++) {
if (i in this && this[i] === item)
return i;
}
return -1;
};
arr = ["foo", "bar"];
__indexOf.call(arr, "foo") >= 0;
也具有過濾器when
prisoners = ["Roger", "Roderick", "Brian"]
release prisoner for prisoner in prisoners when prisoner[0] is "R"
看起來很像普通英語了,也可以用()收集遍歷的結(jié)果
result = (item for item in array when item.name is "test")
流程控制
CoffeeScript使用來自ruby的省略語法,讓控制流變得很緊湊,也引進(jìn)了unless,not,then等語法糖式的關(guān)鍵字
result = if not true then "false"
result = unless true then "false"
取消了js中的==判斷,改成全部用===進(jìn)行嚴(yán)格比較,js中的==會做大量詭異的類型轉(zhuǎn)換,很多情況下是bug的來源
if "1" == 1
alert("equal")
else
alert("not equal")
在使用if來進(jìn)行空值的判斷時,js有時會讓人困擾,因為""和0都會被轉(zhuǎn)換成false,Coffee提供了?操作符解決這個問題,她只有在變量為null或undefined時才為false
""? #true
null? #false
也可以用常見的類似ruby中||=的方法,判斷賦值,此外還可以用and,or,is關(guān)鍵字代替&&,||,==
hash or= {}
hash ?= {}
經(jīng)常有當(dāng)某個屬性存在的時候,才會調(diào)用屬性上的方法的情況,這時候也可以用?
knight.hasSword()?.poke()
只有當(dāng)hasSword()返回對象不為空時,才會調(diào)用poke方法,以下是編譯的js代碼
var _ref;
if ((_ref = knight.hasSword()) != null) {
_ref.poke();
}
switch case語句也有了一些語法糖,并且會默認(rèn)加上break
switch day
when "Sun" then go relax
when "Sat" then go dancing
else go work
函數(shù)
CoffeeScript對JavaScript的函數(shù)做了很大的簡化,舉個例子,看一個求和函數(shù)
sum = (nums...) ->
nums.reduce (x, y) -> x+y
sum 1,2,3
對應(yīng)JavaScript
var sum,
__slice = [].slice;
sum = function() {
var nums;
nums = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return nums.reduce(function(x, y) {
return x + y;
});
};
sum(1, 2, 3);
- 可以使用和ruby 1.9類似的lambda函數(shù)寫法->來代替function
- 參數(shù)列表放在->的前邊,且可省略
- 取消了函數(shù)聲明,只能將函數(shù)作為值定義
- 在CoffeeScript中,任何語句都是表達(dá)式(除了break和continue),都有返回值,因此像ruby一樣,不需要顯- 式return
- js的函數(shù)參數(shù)有一個很討厭的地方,就是參數(shù)對象arguments不是一個真正的數(shù)組,要使用數(shù)組方法,必須- 轉(zhuǎn)換成數(shù)組[].slice.call(arguments, 0)這樣,而在CoffeeScript中收束(加...)的參數(shù)是一個真正的數(shù)組
CoffeeScript的函數(shù)可以有默認(rèn)參數(shù),如
times = (a = 1, b = 2) -> a * b
CoffeeScript的函數(shù)調(diào)用可以不用()語法包圍參數(shù),像ruby一樣跟在函數(shù)名后面就可以,不過這也有時候會帶來問題,特別是沒有參數(shù)的調(diào)用
alert
總結(jié)
如果有興趣的小伙伴,可以到coffeeScript中文網(wǎng) ,繼續(xù)學(xué)習(xí)。
雖然是一個糖果版的JavaScript,但是還是 給予javaScript,對于學(xué)習(xí)專研,還是要以javaScript為準(zhǔn)。至于CoffeeScript是一個非常好的書寫規(guī)范,讓javaScript更加簡潔易懂。ES6的出現(xiàn)也是根據(jù)CoffeeScript的亮點進(jìn)行優(yōu)化的。所以目前ES6已經(jīng)覆蓋了CoffeeScript的70%的功能點了。隨著ES2017將在6月份推出,相信有更多的驚喜值得我們發(fā)現(xiàn)!