第一章 CoffeeScript初学者

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

字符串内插可以使我们的代码更简单易读。

布尔值

布尔值就是那些为真或假的值。它们仅使用truefalse这样的单词来标记,而不使用引号标记。

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)

推荐阅读更多精彩内容

  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 1,272评论 0 4
  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 2,448评论 3 44
  • 使用iTunes、iTools、PP助手类似软件下载iOS项目的ipa包 解压下载好的ipa包 进入解压后的文件夹...
    沈正方阅读 733评论 0 0
  • 窗外,淅淅沥沥的下着小雨,阴沉的天幕似乎在诉说着什么。不知道此刻在雨中踌躇的人们,是忘了打伞,还是在倾听着雨的细语...
    Allen赵阅读 93评论 0 0
  • 123
    明明白白我的鑫阅读 37评论 0 0