# When using a JavaScript loop to generate functions,
# it's common to insert a closure wrapper in order to ensure that loop variables are closed over,
# and all the generated functions don't just share the final values.
# CoffeeScript provides the do keyword,
# which immediately invokes a passed function, forwarding any arguments.
for filename in list
do (filename) ->
fs.readFile filename, (err, contents) ->
compile filename, contents.toString()
# To step through a range comprehension in fixed-size chunks, use by, for example:
evens = (x for x in [0..10] by 2)
# Health conscious meal.
foods = ['broccoli', 'spinach', 'chocolate']
eat food for food in foods when food isnt 'chocolate'
# Comprehensions can also be used to iterate over the keys and values in an object.
# Use of to signal comprehension over the properties of an object instead of the values in an array.
yearsOld = max: 10, ida: 9, tim: 11
ages = for child, age of yearsOld
"#{child} is #{age}
CoffeeScript |
JavaScript |
is |
=== |
isnt |
!== |
not |
! |
and |
&& |
or |
ll |
true,yes, on |
true |
false, |
no, off |
@,this |
this |
of |
in |
in |
no JS equivalent |
# It's a little difficult to check for the existence of a variable in JavaScript.
# if (variable) ... comes close, but fails for zero, the empty string, and false.
# CoffeeScript's existential operator ? returns true unless a variable is null or undefined,
# which makes it analogous to Ruby's nil?
# It can also be used for safer conditional assignment than ||= provides,
# for cases where you may be handling numbers or strings.
speed ?= 15
footprints = yeti ? "bear"
# The accessor variant of the existential operator ?.
# can be used to soak up null references in a chain of properties.
# Use it instead of the dot accessor . in cases where the base value may be null or undefined.
# If all of the properties exist then you'll get the expected result,
# if the chain is broken, undefined is returned instead of the TypeError that would be raised otherwise
zip = lottery.drawWinner?().address?.zipcode
# :: gives you quick access to an object's prototype;
# and super() is converted into a call against the immediate ancestor's method of the same name.
String::repeat = (n) ->
Array(n + 1).join @
String::downcase = ->
@toLowerCase()
String::upcase = ->
@toUpperCase()
String::find = (str) ->
@indexOf str
String::has = (str) ->
(@indexOf str) > 0
String::dasherize = ->
this.replace /_/g, "-"
# Destructuring Assignment
# it can be used for parallel assignment:
weatherReport = (location) ->
# Make an Ajax request to fetch the weather...
[location, 72, "Mostly Sunny"]
[city, temp, forecast] = weatherReport "Berkeley, CA"
# Destructuring assignment can be used with any depth of array and object nesting,
# to help pull out deeply nested properties.
futurists =
sculptor: "Umberto Boccioni"
painter: "Vladimir Burliuk"
poet:
name: "F.T. Marinetti"
address: [
"Via Roma 42R"
"Bellagio, Italy 22021"
]
{poet: {name, address: [street, city]}} = futurists
# Destructuring assignment can even be combined with splats.
tag = "<impossible>"
[open, contents..., close] = tag.split("")
# function Person(options) {
# this.name = options.name, this.age = options.age, this.height = options.height;
# }
class Person
constructor: (options) ->
{@name, @age, @height} = options
CoffeeScript -> 與 => 的差別
# => 用來this 是傳進來的東西時, callback 時會用到
Account = (customer, cart) ->
@customer = customer
@cart = cart
$('.shopping_cart').bind 'click', (event) =>
@customer.purchase @cart
try
allHellBreaksLoose()
catsAndDogsLivingTogether()
catch error
print error
finally
cleanUp()
cholesterol = 127
healthy = 200 > cholesterol > 60
html = """
<strong>
cup of coffeescript
</strong>
"""
# /*
# SkinnyMochaHalfCaffScript Compiler v1.0
# Released under the MIT License
# */
###
SkinnyMochaHalfCaffScript Compiler v1.0
Released under the MIT License
###