1:CoffeeScript初学者
译者注:
本部分介绍CoffeeScript基本语法知识:数学符号运算规则、数据类型(数字和字符串)、变量、布尔值(标记为true或false)、条件语句(if/else)、注释、函数、其他数据类型(数组、循环、对象)。
数学
让我们从一些简单的数学开始。
CoffeeScript支持所有你熟悉的数学运算符号:+ - * /(加,减,乘,除),加一个你或许不熟悉的:%或取模。在原型交互时你将要做的最多的就是简单的数学运算。
快速回顾一下你将要遇到的:
符号运算规则
就像你在高中时学到的一样,BEDMAS(Brackets先算括号里的,Exponents乘方,Division除法,Multiplication乘法,Addition加法,Subtraction减法)任然适用。如果你想在乘法和除法运算之前先进行加法和减法,那就把加法和减法运算放到括号里面去。
在CoffeeScript面板中输入并观察:
10 + 20
# => 25
150 - 5 * 20
# => 50
(150 - 5) * 20
# => 2900
数字和数学将或多或少的遵循你在中学时所记忆的方式。如果你被一些事情困住例如舍入一个数字,那么查看MND数学文档或者只是尝试搜索就可以了。
数据的类型
这里有你可以用来编程的所有不同的数据类型,而且他们中的一些还具有特殊的能力和用途。
数字
数字是最简单的一个。数字就是数字。200,-10,4000都是数字。在你的数字中不要包含逗号和空格就好。CoffeeScript中的数字可以具有小数点,可以有正负。
字符串
当你使用字母,单词或标点工作时,你就在和字符串打交道。字符串用引号标记。任何引号标记的都是字符串。你可以使用单引号或者双引号,但使用双引号时并发症较少。
"This is a string"
'This is also a string'
你可以使用 + 符号把字符串组合在一起。这叫做串联。
"My name is " + "Tessa"
# => "My name is Tessa"
用数字和字符串做事情 因为任何在双引号内的都是字符串,你可以得到实际上是字符串的数字(因为他们被放入双引号中)。"40"是字符串,40是数字。
如果你像数字一样处理字符串,一些奇怪的事就会发生:
"50" + "50"
# => "5050"
不是用数学的方法将两个数字加在一起,而是两个字符串合成在一起。如果其中的一个值是字符串,另一个是数字,我们得到同样的结论:
"50" + 50
# => "5050"
在一些情况中,混合字符串和数字会正常得出结果,但是当你进行数学运算的时候最好避免这样。
使用变量
除了一些简单的数学,我们仅仅用数字、字符串和数学运算符不能做大量的事情。我们组织代码的最有力量的工具之一就是变量。变量让你将一个值标记为任意符号以便后续引用。一个变量就是一个盒子,你可以把值放进去。任何种类的值,像字符串或者一个数字。变量使用 = 符号标记。
name = "Tessa"
print name
# =>"Tessa"
age = 26
print age
# => 26
注意 print命令只是把我们代码的结果输出在一个面板上。在浏览器中,print是不存在的,但是你可以使用 console.log 达到同样的目的。
一个变量会保留你赋予它的这个值知道你将其改变。在你的程序中,你可以随时改变一个变量(因此它的名字叫做变量)。
color = "green"
print "My favorite color is " + color
# => "My favorite color is green"
color = "red"
print "My favorite color is " + color
# => "My favorite color is red"
这里有一些变量的命名规则:
- 变量名不能包含空格
- 变量名不能数字开头
- 变量名不能包含标点和 _ 以外的字符
- 变量名可以包含大写和小写字母
对于变量名称这有一些共同的命名规范和方式。当一个变量名多于两个单词,使用下划线将连个单词连接在一起或者采用“camel casing”(小骆驼拼写法:第一个词首字母小写,以后每个词首字母大写)。
my_name = "Tessa"
myName = "Tessa"
字符串内插
例子 print "my favorite color is " + color 并不都是那么复杂,但是将变量与字符串组合很容易变得凌乱。例如,如果变量出现在字符串中间:
color = "green"
print "my favorite color is " + color + ",what's yours?"
我们不得不使用一串 + 符号,并且记得在什么地方使用空格和标点。这有一个更简单的方式,叫做字符串内插。如果我们用 #{} 包裹变量,那我们可以在字符串中嵌入它:
color = "green"
print "my favorite color is #{color}, what's yours?"
# =>"my favorite color is green,what's yours?"
字符串内插可以使我们的代码更简单易读。
布尔值
布尔值就是那些为真或假的值。它们仅使用true或false这样的单词来标记,而不使用引号标记。
myBoolean = true
布尔值常常是比较的结果(记住数学课上>就是“多于”,<就是“少于”):
10>9
# => true
9<8
# => false
你可以将比较的结果标记为变量:
theTruth = 10 < 5
print theTruth
# => false
同等比较
在普通的数学中,你可以用=来标记比较值。正如你所回忆的,我们已经使用=来标记变量(myVar = 10),所以也使用=来进行比较会让人有一点困惑和容易出错。
在CoffeeScript中,你可以使用is操作符来检查看看2个值是否一样。
注意:你可能看到代码中有的地方==是用来比较值。在CoffeeScript is是==的缩写。我们将使用 is 因为它更易读。
5 is 5
# => true
num = 5
num is 5
# => true
num = 10
# => false
使用关键词 not 来否定一个条件。你可以使用缩写 isnt 来代替 is not
num = 5
num isnt 10
# => true
条件语句
只有在我们使用比较结果做一些事情的时候比较变量才有用。那就是条件语句的作用。CoffeeScript使用简单的 if/else 语句在不同的状态下执行不同的代码:
num = 4
if num >= 16
print "you can learn to drive"
else
print "you're too young to learn to drive"
# => "you're too young to learn to drive"
注意 >= 意味着“大于或等于”就像 <= 意味着少于或等于。
缩进
如果你以前曾看到过其他编程语言像Java或JavaScript,你或许会注意到它们有很多的符号,就像分号和括号。为了更易读写,CoffeeScript避免使用太多这类的符号。为了达到这样的效果,在CoffeeScript中我们需要遵循一些特定的缩进规则。在上面的例子中,if 和 else 语句中的缩进是很重要的。它代表着缩进的代码“属于”这个 if 语句,因此只有条件为真时代码才会执行。
注释
有时你想要在你的代码中给自己或别人留下说明。也许是解释一些事情做了什么,或者提醒自己回顾一些事情,或者帮助组织结构。当你的代码运行的时候,注释不会起作用,所以你可以把它们放在任何你想要的地方。
在CoffeeScript,起始于#的一行会被看成为注释并不会被程序理会。
# this is a comment. It doesn't do anything. But it's nice to read.
函数
函数封装了一些可以被重复使用的代码。例如,上面写的“年龄检查”代码可以被封装在一个函数中,这样每一次遇到年轻司机的问题上使用它。
当你制做一个函数时,你想要某种程度上使用它,所以你必须用一种方式来引用它。要做到这点,我们将函数标记为变量:
checkAge =
为了说明我们在这个变量中放了一个函数,我们使用 -> 箭头
checkAge = ->
# 我们将把检查年龄的代码放这
上面的代码就是在说“checkAge是一个函数”,但它还不能做任何事情。为了“调用”无用的函数(调用 = 执行),我们使用括号。
checkAge = ->
# 还不能做任何事
checkAge()
()部分基本上是指“go”。它在告诉计算机在年龄检查变量上运行函数。
所以我们来让年龄检查函数实际上做一些事情:
checkAge = ->
if age >= 16
print "carry on"
else
print "get out of the car please"
注意:
缩进是很有意义的。封装在 checkAge 函数中的代码都需要缩进一个等级,来表示这些代码属于这个函数。
现在我们可以调用函数:
age = 16
checkAge()
# which will output "carry on" because we set the age variable to 16
让我们用一组年轻的司机来试试:
age = 15
checkAge()
# => "Get out of the car please"
age = 18
checkAge()
# =>"Carry on"
带参数的函数
如果我们可以赋予它们以工作的值,函数就更有用了。这些值被称作参数。如果我们给 checkAge 一个年龄参数,我们就不需要一个额外的年龄变量。
让我们接受年龄参数重写 checkAge 函数。
在CoffeeScript中,通过在 -> 符号前添加括号包含参数名称,可以赋予函数可接受参数的能力:
checkAge=(age) ->
if age >= 16
print "Carry on"
else
print "Get out of the car please"
一旦你把参数名称放进括号中,你就能指代用到这个名字的 age。
当checkAge 函数被调用时 age 就获得它的值。为了给 checkAge 一个 age 参数,我们把值放进括号中:
checkAge(17)
# =>"Carry on"
函数可以有多个参数:
patrol = (age,speed) ->
if speed > 60
if age >= 16
print"Happy speed ticket"
else
print"Get out of the car,kid"
在这个例子中,patrol 函数也带有一个 speed 参数。现在我们只在速度超过60时执行年龄核查。预算消减。
注意在 if speed > 60 语句下嵌套的所有代码是如何缩进一个额外级别的。
为了使用 patrol 函数,我们现在需要把2个值放进括号:第一个是 age,第二个是speed:
patrol(17,70)
# => "Happy speeding ticket"
patrol(17,40)
# =>...(nothing happens)
patrol(15,90)
# =>"Get out of the car,kid"
如果我们忘记填写速度参数:
patrol(16)
# =>undefined
使用预写函数
当你构建动画和交互原型时,你很有可能不必自己编写大量的函数。然而,你将使用相当多的函数,其中大部分由framer.js库提供。
这就是函数非常有用的地方:当你可以向周围分享他们时。在Framer背后的人想出了如何操作屏幕上的每一个像素的所有方法,所以他们将那些有用的代码封装成可被使用的函数。
假设我们正在使用一个提供 licensePlateCheck 函数的库。他有一个车牌号参数。它执行各种复杂的事情来把车牌号与一个人联系起来,查明这个人是否有罪记录,是否有他们的逮捕令,或者这辆车是否被dda盗。你不需要知道任何关于这个函数的事情就可以使用它。你所要知道的就是他需要一个参数,而且这个参数是一个车牌号。对于任何给出的车牌号,如果这个号码与犯罪活动有关 licensePlateCheck 函数会告诉你 true ,反之会告诉你 false。
我们也需要知道需要提供什么类型的参数。在这个例子中,我们需要知道 licensePlate 参数是一个字符串。这就说得通了,它是由字母和数字组成的。
licensePlateCheck("BAD455")
# => true
想要找到这个车牌号有麻烦了做这些就够了。
其他数据类型
字符串,数字和布尔值都是CoffeeScript中最简单的数据类型,但是使用更复杂的数据类型我们可以做更多的事情,像数组(arrays)和对象(objects)。
数组(array)
数组就是多个x项目列表或集合。假设我们想跟踪一个水果列表:
fruits = ["apples","oranges","bananas"]
数组有一些内置的方法(可以使用的函数)来查找有关他们的信息,如长度:
fruits.length
# => 3
你可以通过索引来访问数组中的元素。索引是元素在数组中的位置。
数组是0索引的。意思就是s数组中的第一个项目是项目0,第二个项目是项目1。这在一开始会让人有点困惑,但是你会慢慢习惯的。
要访问数组中的元素,我们方括号包含我们要找的元素的索引。例如,我们想要访问水果数组中的“oranges”:
print fruits[1]
# => "oranges"
由于“oranges”是数组中的项目1(第二个项目)。
添加到数组
使用 push 你可以把新的项目添加到数组中。 push 将你指定的项目添加到数组的最后:
fruits.push("kiwis")
print fruits
# => ["apples","oranges","bananas","kiwis"]
通过数组循环
CoffeeScript中的数组是非常强大的,因为你可以通过数组中不同的项目一边又一遍的重复特定的功能。
控制程序最cch常用的方法之一就是使用循环。循环可以让你对数组中的每一个项目做一些事情。
toUpperCase 是一种字符串属性,可以将其变为大写形式。如果我们想要将水果数组中的每一个元素变为大写字母,我们可以:
fruits[0].toUpperCase()
# => "APPLES"
fruits[1].toUpperCase()
# => "ORANGES"
fruits[2].toUpperCase()
# => "BANANAS"
但是由于我们已经有一个数组来容纳我们的水果列表,使用一个 for 循环会更高效:
for fruits in fruits
fruit.toUpperCase()
# => "APPLES"
# => "ORANGES"
# => "BANANAS"
在英语中,我们读作“对于每一个水果列表中的水果,将那个水果写为大写”
如果我们将它拆开,for 循环做了两件事情:它对数组中的每个项目执行了一次代码,并且通过任何你喜欢的名字来引用当前的“活动”元素。
代码 for fruit in fruits 告诉我们每次通过数组我们都有一个 fruit 变量。这个变量 fruit 指向我们每次t通过的项目。所以第一次通过数组, fruit 指向“apples”,第二次指向“oranges”,依此类推。
如果我们有一组汽车来运行车牌号检查会怎样呢?
plates = ["BRR010","BUU888","NNB001","MBB991"]
让我们用 for 循环检查每一个车牌的犯罪活动:
for plate in plates
licensePlateCheck(plate)
# => false
# => true
# => false
再次说明,缩进很重要。第二行的缩进意味着代码只在 for 循环中执行。
对象
对象是CoffeeScript中最有用的数据类型之一。对象是属性的集合。在程序中,属性是名称和值之间的关联。一个名值对可以是类似于“price:$10”,price是名称,$10是值,或者是“age:30”,age是名称,30是值。
如果一些东西具有属性,你可以把他们放在对象中。例如,一个“book”对象可能具有 title (标题)属性,一个 author (作者)属性,和一个 genre (类别)属性。在CoffeeScript中,我们可以这样写代码:
book =
title:"Slaughterhouse Five"
author:"Kurt Vonnegut"
genre:"Science Fiction"
你可以在对象属性中存储任何类型的数据,包括数组和布尔值:
book =
pages:256
genres:["Science Fiction","Satire"]
fiction:true
你甚至可以在一个属性中存储另一个对象:
book =
author:
name:"Kurt Vonnegut"
born:1992
died:2007
注意上面的例子中我们使用的 = 和 :。注意不同之处:= 表示一个对象的变量名(book),:用于名称和值得匹配。 author 是名字,这个对象所包含的name,born,died是(author的)值。
我们使用点来引用对象成员:
print book.title
# => "Slaughterhouse Five"
print book.pages
# => 1922
我们可以继续使用点引用对象中的对象:
print book.author.born
# => 1922
也可以联合方括号和点号句法来引用对象数组中的元素:
print book.genres[1]
# => "Satire"
方法(Methods)
由于我们可以在对象成员中存储任何数据,我们也可以将函数作为成员存储。当函数作为对象的成员时,它被称为method。
book =
title:"Slaugherhouse Five"
read: ->
print "All this happend,more or less"
read 成员就是一个隶属于 book 对象的方法。我们可以像调用其它函数一样调用它:
book.read()
# =>"All this happended,more or less."
这就是 toUpperCass 方法的工作原理。它是一个方法,隶属于所有字符串函数。
函数和方法有什么区别?区别不大。方法就是一个隶属于对象的函数。所以我们可以说一个字符串有一个 toUpperCass 方法,意味着这个字符串具有一个成员叫做 toUpperCass ,而这个成员是一个函数。
配置对象
在Framer.js中,对象最普遍的使用方式就是配置动画和元素:
box =
width:120
height:120
x:0
y:0
animation =
duration:300
easing:"ease-in"
对象是配置动画和元素的理想选择,因为它们都有许多不同类型的成员(有些是数字,有些是字符串,等等)。
下期内容:2: 简单的动画 (2:Simple Animations)