CoffeeScript编程笔记
2019年08月27日


编程建议

    由于CoffeeScript采用 空白符缩进 来控制语句,如果同级的代码缩进没有对齐(多一个空格和少一个空格)都会对程序结构产生影响,在编译过程中,经常报代码未对齐的错误。

    建议 采用 Tab键 作为缩进符号,一是直观,而是方面增加和减少对齐(如果用4个空格代替Tab,则减少对齐时要删除4个空格,容易出错;如果用2个空格来缩进,程序不够直观,例如下面的代码↓)。

$ 'body'
.click (e) ->
  $ '.box'
  .fadeIn 'fast'
    .addClass 'show'
  .fadeOut 'fast'
.css 'background', 'white'

Tab缩进的如下:

$ 'body'
.click (e) ->
	$ '.box'
	.fadeIn 'fast'
		.addClass 'show'
	.fadeOut 'fast'
.css 'background', 'white'

注意:也可以用 特殊的编辑器(例如vscode),自动使用4个空格替换tab,且一次性删除4个空格。但注意这样的程序放在其他地方,比如Vim编辑器中,就不太好用。


Operators

== 等于 ===
!= 等于 !==
is 等于 ===
isnt 等于 !==
!代表非
and 代表 &&
or 代表 ||

例如:
window.ps or= perfectSquares()
等价于:
window.ps || (window.ps = perfectSquares());
意思是,如果window.ps不存在,则赋值为后面那个函数的值。

unless 代表 if的反面

true, yes, on 代表 true
false, no, off 	代表 false

this.property 简写为 @property
例如,定义一个Class函数:
Account = (customer, cart) ->
    @customer = customer
    @cart = cart


If-Else

1、? 返回 true 除非变量是 null、undefined 或 未声明。

foo = "anything"
bar = false

if foo
	alert "true"
else if bar
    alert "xxx"
else 
	alert 'c'

// 使用?判断变量是否存在
if nonexistent?
	alert "aaa"
else
	alert "bbb"

// if的反面
unless nonexistent?
	alert "aaaa"
else 
	alert "bbb"

// yeti存在,则 foot = yeti,否则 foot = "bear"
foot = yeti ? "bear"


eldest = if 24 > 21 then "Liz" else "Ike"

// if - and 语法
solipsism = true if mind? and world?

// if - and not 语法
solipsism = true if mind? and not world?


// 牛逼的功能
zip = lottery.drawWinner?().address?.zipcode
// 先判断 drawWinner是否为函数,然后再调用,然后再判断address是否存在,然后再调用zipcode
// 等价于:
zip = typeof lottery.drawWinner === "function" ? 
	(_ref = lottery.drawWinner().address) != null ? _ref.zipcode : void 0 
	: void 0;

// 语法如下:
a?.b or a?['b']
a?(b, c) or a? b, c


Loops

0、数组推导

可以直接在 for语句前面 调用当前for的变量,例如:

console.log num for num in [10..1]

直接在for语句前面调用 console.log(num)


也可以在 for语句后面 跟判断语句(when),例如:

foods = ['broccoli', 'spinach', 'chocolate'] 
eat food for food in foods when food isnt 'chocolate'


用 括号 将 for语句包起来,将每次for循环的值,加入到一个数组中,然后返回,例如:

numbers = [9, 8, 7]
result1 = (n*2 for n in numbers)
# result1 = [18, 16, 14]

countdown = (num for num in [10..1]) 
// countdown = [10,9,8,7,6,5,4,3,2,1] 
n = 10 
evens = (x for x in [0..n] by 2) 
// evens = [0,2,4,6,8,10]

也可以在 for语句后面 跟by设置步长,见上面的例子。


1、in 和 of

a in b 等价于 [].indexOf.call(b, a) >= 0

a of b  等价于 a in b

numbers = [9, 8, 7]

# [9, 8, 7]
result0 = (i for n, i of numbers)
result1 = (n for n, i in numbers)


# [0, 1, 2]
result0 = (n for n, i of numbers)
result1 = (i for n, i in numbers)


2、

# Eat lunch.
eat = (food) -> "#{food} eaten."
eat food for food in ['toast', 'cheese', 'wine']
# Health conscious meal.
foods = ['broccoli', 'spinach', 'chocolate']
eat food for food in foods when food isnt 'chocolate'
# Fine five course dining.
courses = ['greens', 'caviar', 'truffles', 'roast', 'cake']
menu = (i, dish) -> "Menu Item #{i}: #{dish}" 
menu i + 1, dish for dish, i in courses

4、

yearsOld = max: 10, ida: 9, tim: 11

ages = for key00, val00 of yearsOld
  "#{key00} is #{val00}"

// 结果 ages是一个数组 ["max is 10", "ida is 9", "tim is 11"]


Array

1、Index

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 等价于 numbers.slice(0, 3)
start   = numbers[0..2]

middle  = numbers[3...-2]

end     = numbers[-2..]

copy    = numbers[..]

numbers[3..6] = [-3, -4, -5, -6]