coffeescript


原文链接: coffeescript

功能array comprehensions, prototype aliases and classes
##语法
没有分号。使用缩进来代替花括号。

###注释
注释格式与ruby一致,以井号开头

# A comment

支持多行注释,多行注释会添加到生成的javascript中

###
	A multiline comment
###

###变量与作用域
编译时,CoffeeScript使用一个匿名函数把所有脚本都包裹起来,将其限定在局部作用域中,并且为所有的变量赋值前自动添加var。

可以通过下面的方式创建全局变量

exports = this
exports.MyVariable = "foo-bar"

###数组和对象
花括号可以省略,分割用的逗号可以通过换行省略。中括号不能省略。

object1 = {one: 1, two: 2}

# Without braces
object2 = one: 1, two: 2

# Using new lines instead of commas
object3 =
  one: 1
  two: 2

song = ["do", "re", "mi", "fa", "so"]

bitlist = [
  1, 0, 1
  0, 0, 1
  1, 1, 0
]

###函数
函数通过一组可选的圆括号包裹的参数, 一个箭头, 一个函数体来定义. 一个空的函数像是这样: ->
。函数可以是一行,也可以是多行。函数的最后一个表达式回作为隐式的返回值。

square=(x) -> x*x

####参数默认值
一些函数函数参数会有默认值, 当传入的参数的不存在 (null 或者 undefined) 时会被使用.

fill = (container, liquid = "coffee") ->
  "Filling the #{container} with #{liquid}..."

####变参
使用...表示

sum = (nums...) ->
  result = 0
  nums.forEach (n) -> result += n
  result

nums 不是一个arguments 对象,而是一个真数组。

####函数调用
无参数调用函数时需要加括号。如果函数被至少一个参数跟着的话,coffeescript会自动调用这个函数。

####函数上下文
使用胖箭头=>,可以确保函数的上下文绑定为当前的上下文。

this.clickHandler = -> alert "clicked"
element.addEventListener "click", (e) => this.clickHandler(e)

这种绑定的思想与jQuery的 proxy()或者ES5's的bind()函数是类似的概念。

###流程控制
if/else 表达式可以不用圆括号和花括号就写出来. 就像函数和其他块级表达式那样, 多行的条件可以通过缩进来表明.

if happy and knowsIt
  clapsHands()
  chaChaCha()
else if
  showIt()
else
  bongbong()

coffeescript支持一项ruby特性,在if语句之前使用前缀表达式。

mood = greatlyImproved if singing

unless 是if的否定

####三元表达式
CoffeeScript 里不存在直白的三元表达式. — 你只要在一行内使用普通的 if 语句。在单行if语句中必须使用then关键字,这样coffeescript才能知道执行体从哪里开始。

date = if friday then sue else jill

####存在操作符
CoffeeScript存在操作符?只会在变量为null或者undefined的时候会返回真,与Ruby的nil?类似。

###操作符和别名

coffeescriptjavascript
is===
isnt!==
not!
and&&
or
true,yes,ontrue
false,no,offfalse
@,thisthis
ofin
inno js equivalent
::prototype

###字符串插值

在双引号的字符串中可以包含#{}标记,用来插入表达式。

favourite_color = "Blue. No, yel..."
question = "Bridgekeeper: What... is your favourite color?
            Galahad: #{favourite_color}
            Bridgekeeper: Wrong!
            "

允许多行字符串,无需+
###循环和列表解析

JavaScript中的数组迭代使用一种相当古老的语法,看上去更像一个类似于C之类的老语言,而不是现代的面向对象的语言。ES5引入forEach()函数来稍微改善了下这种情况,但是这样的话每次迭代都需要调用一次函数,因此运行速度会变慢。再一次,CoffeeScript给出一种漂亮的语法拯救了我们:

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"]

就如Python的推导式一样,你可以过滤它们:

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暴露出来的底层循环语法是while循环。它与原JavaScript中while循环的行为差不多,只是包含了已添加的优点,它能返回一个结果数组。看起来像Array.prototype.map()函数。

num = 6
minstrel = while num -= 1
  num + " Brave Sir Robin ran away"
`