CoffeeScript Notes

Posted by Deividy Metheler Zachetti on July 28, 2013

This is my study book of CoffeeScript Accelerated JavaScript Development.

Embedding JS in CS

  • Just put your JS code surrounding it with backticks

     console.log `impatient ? useBackticks() : learnCoffeeScript()`
    
  • CS wraps code for namespacing, but you can remove it with -b (‘bare’) flag
  • we can execute a function using do

     do fn
     fn()
    
  • A function will be always defined with var, in CS we have no way to define functions with function keyword, the one exception is when we use the class keyword
  • Strict equality or Nothing, CS dont provide anyway to use the equality comparator of JS (==), is and == will always do strict equality

Again; - Every function creates a scope, and the only way to create a scope is to define a function - A variable lives in the outermost scope in which an assignment has been made to that variable - Outside of its scope, a variable is invisible

Variable’s scope is defined explicitly in JS using the var keyword while CS infers scope from assignments.

  • Shadowing variable name is a bad thing, dont do this

     x = 5
     triple = (x) -> x *= 3
     triple x                // => 15
     x                       // => 5
    
     hey = (x = x) -> console.log x
     hey()                   // => undefined
     x                       // => 5
    
  • context = this
  • scope = where the variable’s are resolved
  • The context is determined purely by how a function is called; unlike scope, it has nothing to do with where the function is defined.

  • When the new keyword is put in front of a function call, its context is the new object.
  • When a function is called with call or apply, the context is the first argument given.
  • Otherwise, if a function is called as an object property (obj.func) or ob[“func”], it runs in that object’s context.

  • How => works

     callback = (message) => @voicemail.push message
    
     var callback;
     callback = (function(__this) {
         var __func = function (message) {
             return this.voicemail.push(message);
         };
         return function () {
             return __func.apply(__this, arguments);
         };
     })(this);
    
  • You can use arbitrary expressions as default arguments, the expression will be execute from whatever context the function is being called in.

spoiler = (filter..., theEnding) -> console.log theEnding
spoiler 'Darth Vader is Luke\'s father!'              // => 'Darth Vader is Luke's father!'

birds = [ 'duck', 'duck', 'duck', 'coffee!' ]
[ ducks..., coffee ] = birds
ducks                                                 // => 'duck, duck, duck'
coffee                                                // => 'coffee'

Collections and Iteration

  • In JS every object is a hash, and almost everything is an Object. Except primitive values (booleans, numbers and strings) and special constants like undefined and NaN
  • When the CS compiler sees :, it know that you’re building an object.

     drawSprite x, y, invert:true
    
     drawSprite(x, y, {
         invert: true
     });
    
  • Same-Name Key-Value Pairs { me }, works only with explicit curly braces
  • Soaks ‘a?.b’

     cats?['Garfield']?.eat() if lasagna?
    
     abc = [ 'a', 'b', 'c', 'd' ]
     abc[0..-1]                      # => [ 'a', 'b', 'c' ]
     abc[2..0]                       # => [ ]: always will be empty if the first number is greater than secound
    

.. defines an inclusive range … defines a exclusive range

    [1..5]                          # => [1, 2, 3, 4, 5]
    [1...5]                         # => [1, 2, 3, 4]
  • we can use splice with ranges to

     arr = ['a', 'c']
     ar[1...2] = [ 'b' ]             # => ['a', 'b']
    
  • Curiously, JS provides strings with a slice method, even though its behavior is identical to substring. This is handy, because it means you can use CoffeeScript’s slicing syntax to get substrings.

     'The year is 2013'[-4..]        # => 2013
    
  • hasOwnProperty, for own

     for own sword of Kahless
    
    
     for sword of Kahless
         continue unless Kahless.hasOwnProperty(sword)
    
  • with for.. of we can use when
  • with for.. in and array like we can use by

  • When you write for x of obj or for x in arr, you’re making assignments to a variable named x in the current scope. You can take advantage of this by using those variables after the loop.
  • We can use do to capture the loop variable on each iteration

     for name, occupation of murderMysteryCharacters
         break if occupation is 'butler'
    
     console.log "#{name} did it!"
    
     for x in arr
         do (x) ->
             setTimeout (-> console.log x), 0
    
  • while, until and loop
  • loop is forever until break

Pattern Matching (or, Destructuring Assignment)

  • It’s NOT an array or an object, its a Pattern

    [firstName, middleInitial, lastName] = ['Joe', 'T', 'Plumber']
    # firstName = 'Joe'; middleInitial = 'T'; lastName = 'Plumber'
    
    myRect =
        x: 100
        y: 200
    {x: myX, y: myY} = myRect
    
    {languages: [favoriteLanguage, otherLanguages...]} = resume
    # Take resume.languages, assign its first entry to a vari- able called favoriteLanguage, then assign the remaining entries to a new array called otherLanguages.
    
  • Better to use many small files, each with a WELL-DEFINED PURPOSE! than a few large files that make readers feel like rats in a maze.

  • always use the root object to set a global property

     class Tribble
         constructor: () ->
             @isAlive = true
             Tribble.count++
            
         breed: () ->
             return new Tribble if (@isAlive)
            
         die: () ->
             Tribble.count-- if (@isAlive)
             @isAlive = false
    
         @count: 0
         @makeTrouble: () ->
             console.log ('Trouble!' for i in [1..@count]).join(' ')
    
  • the object itself
  • the prototype object
  • and the instance

  • ’ strict string
  • You can use “”” to write multilines strings in a human-readable format.

Docco

### Eco ### Zappa ### Zombie.js