Estos son los apuntes de Coffescript de Arnoldo Rodriguez, uno de los profesores de DesafioLatam, en Monterrey, México, están muy buenos, especialmente si quieres recorrer de forma rápida todas las virtudes que tiene coffeescript.
Comments in CoffeeScript
# single line comment
###
multiline comment, perhaps a LICENSE.
###
Variables and Scope
# All variables are by default scoped locally
my_var = "Hello world"
pi = 3.1416
# Attach a variable to the global or window object to make it global
window.my_var = "Hello world"
Functions
# use the slim arrow to declare a function
func = -> "bar"
sumXtoTen = (x) ->
10 + x
# arguments are specified in parenthesis before the arrow
times = (a, b) -> a * b
# you can specify default arguments
times = (a = 10, b = 15) -> a * b
# use splats to receive N arguments via an array
sum = (nums...) ->
result = 0
nums.reduce (total, num) -> total + num
# you can avoid parethesis in function calls with at least 1 argument
alert "hello world"
console.log "this is the end"
# on the contrary you cannot call a function without parenthesis and zero
# arguments
# this fails
alert
# this is O.K.
alert()
# use the fat arrow to bound a function call to the local context
# mostly used in callbacks
# avoid using the conventional self = this is not very coffeescriptish
this.clickHandler = -> alert "clicked"
element.addEventListener "click", (e) => this.clickHandler(e)
Objects Literals and Array Definition
# Object literals
# regular Javascript syntaxis
object1 = {one: 1, two: 2}
# without braces
object2 = one: 1, two: 2
# using new lines instead of commands
object3 =
one: 1
two: 2
# Arrays
# avoid the trailing comma
array1 = [1, 2, 3]
# using new lines
array2 = [
1
2
3
]
Flow Control
# ruby style one liners if and unless
alert("Hello world") if sayHi is yes
alert("Hello world") unless sayHi isnt yes
# one liner if then or ternary
if true isnt true then "Panic"
if true isnt true then "Panic" else "Everything just works!"
# use plain old english for not, is, isnt, and, or
if not true then "Panic"
if true is true then "Everything's gonna be allright"
if true isnt true then "We'll burn in hell!!"
if total is 0 and discount is 0 then "God save us all!"
String Interpolation
# oh good old ruby and multiline strings also!
favoriteColor = "Blue. No, yel..."
question = "Bridgekeeper: What... is your favorite color?
Galahad: #{favoriteColor}
Bridgekeeper: Wrong!
"
Loops and Comprehensions
# Iterate over the array's elements
for name in ["Roger", "Roderick"]
alert "Release #{name}"
# using index
for name, i in ["Roger", "Roderick"]
alert "#{i} - Release #{name}"
# one liner
release prisioner for prisioner in ["Roger", "Roderick"]
# use keyword when to filter or select
release prisioner for prisioner in ["Roger", "Roderick"] when prisioner[0] is "R"
# use comprehensions to iterate over an object's properties
names = sam: seaborn, donna: moss
alert("#{first} #{last}") for first, last of names
# use low leve while be aware that it returns an array of results like a map
num = 6
minstrel = while num -= 1
num + " Brave Sir Robin ran away"
# slicing an array/ string with ranges
firstTwo = ["one", "two", "three"][0..1]
my = "my string"[0..1]
# includes or checking existence
words = ["rattled", "roudy", "rebbles", "ranks"]
alert "Stop wagging me" if "ranks" in words
# a map
names = (muppet.name for muppet in muppets)
# a filter or select
names = (muppe.name for muppet in muppets when muppet.name isnt "peggy")
# property iteration over an object
object = {one: 1, two: 2}
alert("#{key} = #{value}") for key, value of object
Aliases and the Existencial Operator
# @ is an alias for this
this.saviour = true
@saviour = true
# :: is an alias for prototype
User.prototype.first = -> @records[0]
User::first = -> @records[0]
# the ? symbols returns true unless null or undefined
praise if brian?
# use ? in place of || operator
velocity = souther ? 40
# use ? before accessing a property, similar to Active Support's try method
blacknight.getLegs()?.kick()
# check if a property is a function and callable
blacknight.getLegs().kick?()
# use it for initialization
hash ?= {}
# Modules: you can create modules using the do notation
FormHelpers = do ->
# Public methods
textFieldTag: () ->
selectTag: () ->
labelTag: () ->
# Private methods
_initTextField = () ->
_buildLabelTag = () ->
Classes
# basic class structure
class Animal
# constant
@BASE_PRICE: 100.00
# basic initializer or constructur
constructor: (args = {}) ->
# instance variables
@name = args.name
@species = args.species
# instance method
sell: (customer) ->
# accessing constant
@constructor.BASE_PRICE
# class method
@find: (name) ->
# use fat arrow in callbacks to keep the right context
class Animal
price: 5
sell: =>
alert "Give me #{@price} shillings!"
animal = new Animal
$("#sell").click(animal.sell)
# Inheritance and Super
# use extends to inherit all the instance properties
class Animal
constructor: (@name) ->
alive: ->
false
class Parrot extends Animal
constructor: ->
# use super to call the parents method
super("Parrot")
dead: ->
not @alive()
# Mixins to share common behavior or roles
# there's no native support in coffee but you can implement it
extend = (obj, mixin) ->
obj[name] = method for name, method of mixin
obj
include = (klass, mixin) ->
extend klass.prototype, mixin
# usage
include Parrot,
isDeceased: true
(new Parrot).isDeceased
Rails, Coffeescript using modules
###
This approach can be useful if you have a simple touch of js in your apps and still keeping your code decoupled
lets say, using jquery, some plugins, animations, effects
###
###
First: Create namespaces and containers for your view modules
app/assets/my_app.coffee
###
window.MyApp =
ViewHelpers:
Orders: {}
Customers: {}
Shared: {}
###
Second: For each html view with specific js behaviour create a my_view_name.coffee file
and use the Module pattern
app/assets/my_app/view_helpers/orders/index.coffee
###
MyApp.ViewHelpers.Orders.Index = do ->
# Private interface
# Place helper methods only called from inside the module
_sayHi = (name) ->
alert(name)
# Public interface
# Place here methods that should be called from the outside
init: ->
_sayHi("Mr. Satan")
###
Third: Fire the desired behaviour in your view after the dom is ready
app/views/orders/index.html.erb
###
<% content_for :local_js %>
<script>
$(function(){
MyApp.ViewHelpers.Orders.Index.init();
});
</script>
<% end %>
###
Finally: Include the my_app.coffee file in your application.coffee
app/assets/application.coffee
###
#=require my_app.coffee
Rails, Coffeescript and KnockoutJS
###
First: Define an MV structure for your javascript code under
app/assets/javascripts
###
your_app_name/
models/
views/
utils/
your_app_name.coffee
###
Second: Define global variables/namespaces to load each object type
inside my_appname.coffee
###
#=require_self
#=require jquery
#=require knockout
#=require_tree
window.YourAppName:
Models: {}
Views:
Users: {}
Posts: {}
Utils: {}
###
Third: Place every model, view or utility class in their folder
use class YourAppName.Models.User, class YourAppName.Views.Users.Create
pattern to defined each class name and keeping them under their scopes
###
class YourAppName.Models.User
constructor: (args = {}) ->
class YourAppName.Views.Users.Show
constructor: ->
# Fourth: Create objects and apply knockout bindings (or any other binding library) in the views show.html.erb
<!-- ko with: user --!>
<span data-bind="text: firstName"></span>
<span data-bind="text: lastName"></span>
<!-- /ko --!>
<script>
ko.applyBindings(new YourAppName.Views.Users.Show());
</script>
# Fifth and last, require your_appname.coffee script inside your rails application.js
#=require your_app_name
Gonzalo Sánchez
Director de DesafíoLatam. Ingeniero Civil Informático de la Universidad Federico Santa María. Emprendedor lean, dedicado al desarrollo de una mejor web con ruby on rails. Fanático de los números y las métricas, la música y la fotografía.
Artículos relacionados
Recibe los artículos más leidos y beneficios especiales de nuestra academia
Empieza a trabajar en los roles digitales mejor pagados
Fórmate de manera práctica, e intensiva, con sesiones en vivo de forma flexible y efectiva. Te acompañamos desde que partes hasta que encuentras trabajo.