npm install -g coffee-script(全局)
coffee –compile my-script.coffee
# (单行) ###(多行)
eg.
func = -> "bar" var func;
func = function() {
<==> return "bar";
};
使用参数槽(splats)接收多个参数,使用…表示:
sum = (nums...) ->
result = 0
nums.forEach (n) -> result += n
result
在上面的例子中,nums是一个包含传递给函数全部参数的数组。它不是一个arugments对 象,而是一个真实的数组对象,这样的话在你想操作它的时候就不需要先使用 Array.prototype.splice或者jQuery.makeArray()了。
trigger = (events…) ->
events.splice(1, 0, this)
this.constructor.trigger.apply(events)
胖箭头代替普通箭头是为了确保函数的上下文可以绑定为当前的上下文
this.clickHandler = -> alert "clicked"
element.addEventListener "click", (e) =>this.clickHandler(e)
原因:来自addEventListener的回调函数会以element为上下文 被调用,也就是说,this就相当于这个元素。如果你想让this等于当前上下文,除了使用 self=this,胖箭头也是一种方式。
在单行的if语句中,需要使用then关键字,这样CoffeeScirpt才能明白执行体从什么地方开始。CoffeeScript并不支持条件运算符,作为替代你应该使用单行的if/else 语句。
if true != true then "Panic"
# equivqlent to:
# (1 > 0) ? "ok" : "y2k!"
if 1 > 0 then "Ok" else "Y2K!"
CoffeeScript还支持一项Ruby的特性,即运行在if语句前使用前缀表达式 alert “It’s cold!” if heat < 5
在双引号的字符串中可以 包含#{}标记,这些标记中可以包含被插入到字符串中的表达式。
favourite_color = "Blue. No, yel..."
question = "Bridgekeeper: What... is your favourite color?
Galahad: #{favourite_color}
Bridgekeeper: Wrong!
"
for name in ["Roger", "Roderick", "Brian"]
alert "Release #{name}"
for name, i in ["Roger the pickpocket", "Roderick the robber"]
alert "#{i} - Release #{name}"
一行代码完成迭代。
release prisoner for prisoner in ["Roger", "Roderick", "Brian"]
过滤:
prisoners = ["Roger", "Roderick", "Brian"]
release prisoner for prisoner in prisoners when prisoner[0] is "R"
使用推导式来迭代对象的全部属性,不过要使用of代替in关键字。
names = sam: seaborn, donna: moss
alert("#{first} #{last}") for first, last of names
如果区间被指定到一个变量之后,CoffeeScript则会将其转换为一个slice()调用
firstTwo = ["one", "two", "three"][0..1]
区间会返回一个只包含原始数组的前两个元素的新的字符串。你也可以使 用同样的语法来把数组中的某个片段替换为其他的数组
numbers = [0..9]
numbers[3..5] = [-3, -4, -5]
检测数组中是否存在某个值,使用in操作符
words = ["rattled", "roudy", "rebbles", "ranks"]
alert "Stop wagging me" if "ranks" in words
CoffeeScript使用JavaScript原生的原型来产生类,为静态变量继承以及上下文持久 化添加了一点语法糖,而暴露给开发者的全部只有一个class关键字
class Animal
Animal是类的名字,而且也是你可以用来创建实例的合成的变量的名字。 CoffeeScript在背后使用了一个构造函数,这意味着你可以使用new关键字来实例化变量。
animal = new Animal
可以非常直接地为类添加实例属性,与为对象添加属性的语法一样。只需要在类体内对属性采用合理的缩进即可
class Animal price: 5
sell: (customer) ->
animal = new Animal
animal.sell(new Customer)
使用@作为this的别名,这能让你更加便捷的定义静态属性:
class Animal
@find: (name) ->
Animal.find("Parrot")
使用extends关键字来使用继承
class Animal
constructor: (@name) ->
alive: -> false
class Parrot extends Animal constructor: ->
super("Parrot")
dead: ->
not @alive()
CoffeeSript使用原型继承来自动的从类实例上继承所有的属性,这保证了类的动态性
较之于继承只能实现 从单一的父类继承,Mixins的优势是能够实现多个继承。
extend = (obj, mixin) ->
obj[name] = method for name, method of mixin
obj
include = (klass, mixin) ->
extend klass.prototype, mixin
# Usage
include Parrot,
isDeceased: true
(new Parrot).isDeceased
把Mixins集成到CoffeeScript的类中 吧。我们将会定义一个名为Module的类,然后可以继承这个类来获得对Mixins的支持Module会有两个静态方法,@extend()和@include(),可以用它们来实现对类的静态属 性和实例属性的扩展。
myFunction(item) for item in array
这种语法易读简洁(我想你也这么认为),而且更棒的是这在背后会被编译为for循环。换 句话说CoffeeScript的语法提供了forEach()的便捷,但是没有性能的损耗,也不需要shim 的辅助。
使用列表解析获得与map()同样的行为。注意最好使用括号 把列表解析包裹起来,以便能够完全地确保列表解析返回你所想要的东西——映射后的数组。
result = (item.name for item in array)
CoffeeScript的基础语法使用when关键字通过一个比较来过滤数组项。在背后会产生一个for循环,整个运行过程都包裹在一个匿名函数中,以防止作用域泄漏或变量冲突。
result = (item for item in array when item.name is "test")
别忘了使用括号,否则result是数组的最后一项。
in方法。
included = "test" in array
在背后,CoffeeScript使用的是 Array.prototype.indexOf(),必要的话提供shim方法 来检测数组中是否有某个特定值,不幸的的是同样的in语法并不能在字符串中工作。我们 退回去使用indexOf()函数,查看其返回值是否是负值:
of方法:
object = {one: 1, two: 2}
alert("#{key} = #{value}") for key, value of object
如你所见,你可以同时指定属性名和属性值,非常方便。
Math.max 和 Math.min接受多个参数
因此你可以简单的地使用…来向它们传递数组,从中检索出最 大值和最小值。
Math.max [14, 35, -7, 46, 98]... # 98
Math.min [14, 35, -7, 46, 98]... # -7
这个技巧对于超大的数组也会失败,因为浏览器对传递个函数的参数数量有限制
使用…来结构数组作为多个参数传递给max方法。在背 后,CoffeeScript将其转化为一个使用appply()的函数调用,以确保数组能够作为多个参 数传递给max。在别的地方也可以使用这个特性,比方说代理函数:
CoffeeScript编程风格推荐使用or代替||,使用and代替&&,
可以使用is代替==,isnt代替!=
CoffeeScript中的do关键字能够让我们立即运行函数,这是一种非常有效的包装作用域和受 保护变量的方式
Cake是一个超级简单的与 Make和 Rake类似的构建工具。该库被捆绑在coffee-script 的npm安装包中,可以通过名为cake的可执行程序来使用。