CoffeeScript

今天和大家介紹一個有趣的東西....

介紹

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)!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容