COFFEESCRIPT:









ONLY THE GOOD PARTS

INTRO


# programming language that compiles into JavaScript

# highly influenced by Python and Ruby

# encapsulates JavaScript best practices


rule #1: it's just javascript


# You write this:

do -> 

   str = "hello world!"

   alert str

// Browser sees this:

(function() {

    var str = "hello world!";

    alert(str);

})();

Your first cup: Basic concepts

# No need for var, no semicolons, scoping becomes intuitive

num = 12
var num;
num = 12;

# Functions resemble C# lambda expressions

foo = (x, y) -> x + y
foo = function(x, y) {
    return x + y;
}

# Whitespace is significant

foo = ->
    alert "hello world"
x = 15
foo = function() {
    return alert("hello world");
}
x = 15;

# var, return, (), [], and ; are often implied

foo bar
opts =
    color: "red"
    size:
        height: 45
        width: 150
    success: ->
        console.log "ok"
foo(bar);
var opts = {
    color: "red",
    size: {
        height: 45,
    width: 150
    },
    success: function() {
        console.log("ok");
    }
};

# Syntactic shortcuts

x = (y, z) ->
    y + z
var x = function(y, z) {
    return y + z;
};

coffee = (message="Some Coffee?") ->
answer = confirm message
"Your answer is #{answer}"
var coffee;
coffee = function(message) {
var answer;
if (message == null){
message = "Some Coffee?";
}
answer = confirm(message);
return "Your answer is " + answer;
}

# Designed to look more like a natural language

if light is on then alert "on"
else alert "off"
if (light === true) {
    alert("on");
} else {
    alert("off");
}
x = 12 unless y
if (!y) {
    x = 12;
}
x = if y then 12 else 15
if (y) {
    x = 12;
} else {
    x = 15;
}

# Designed to reduce common mistakes

if x is 4
if x == 4
if x?
if (x === 4)
if (x === 4)
if (typeof x !== "undefined" 
    && x !== null)

Have some sugar with your syntax

# this == @ == this

this.foo()
@.foo()
@foo()
this.foo();
this.foo();
this.foo();

# JavaScript's missing string formatter

alert "#{ a }...#{ b + c }...#{ d }"
alert(a + "..." + (b + c) + "..." + d);

# IIFEs, too

do ($ = jQuery) ->
  x = 5
  $('div').on 'click', ->
    $(@).html x
(function($) {
  var x = 5;
  $('div').on('click', function() {
    $(this).html(x);
  });
})(jQuery);

# Loop over collections without writing a novel

alert num for num in [1, 2, 3]
var _arr = [1, 2, 3];
for (var i = 0; i < _arr.length; i++) {
   alert(_arr[i]);
}
alert num, i for num, i in {a, b, c}
var _obj = {a: a, b: b, c: c};
for (var i = 0; i < _obj.length; i++) {
   alert(_obj[i], i);
}

# Fill and consume lists easily

x = [1..7]
y = [1...7]

plus3 = (z + 3 for z in [1..5])
var x = [1, 2, 3, 4, 5, 6, 7];
var y = [1, 2, 3, 4, 5, 6];

var _arr = [1, 2, 3, 4, 5], plus3 = [];
for (var i = 0; i < _arr.length; i++) {
    plus3.push(_arr[i] + 3);
}

# Multi-line strings!

str = """
  the quick 
  brown 
  fox 
"""
str = "the quick \nbrown \nfox";

# Multi-line regex with comments!

regex = ///
  \b      #word break
  limit-
  (\d+)   #capture this number
///i
regex = /\blimit-(\d+)/i

# Multi-line comments! Okay, not new.

###
  But putting comments
  in regular expressions
  is pretty cool, right?
###
/*
  Free haiku with DevSession
*/

Other sweet ingredients

# Compile-time context binding operator

foo = (name) =>
   @name = name
var __this = this;
var foo = function (name) {
  __this.name = name;
};

# Lexical scoping and variable safety

outer = 1
changeNumbers = ->
  inner = -1
  outer = 10
inner = changeNumbers()
var changeNumbers, inner, outer;
outer = 1;
changeNumbers = function() {
  var inner;
  inner = -1;
  return outer = 10;
};
inner = changeNumbers();

# Automatic property binding (useful for constructors)

foo = (@a, @b) ->
var foo = function (a, b) {
  this.a = a;
  this.b = b;
};
//yes, it does the same thing
foo = (options) ->
    {@a, @b, @c} = options
var foo = function (options) {
  this.a = options.a;
  this.b = options.b;
  this.c = options.c;
};

# And favorite, the existential operator

a = true if b? and not c?
if ((b != null) && (c == null)) { 
  a = true; 
}
options ?= {}
if (options == null) {
  options = {};
}
foo?.bar?.baz?().quux()
if (foo !== null
  && foo.bar != null
  && typeof foo.bar.baz === "function") {
  x = foo.bar.baz().quux();
} else {
  x = void(0);
}

Splat...variadic functions made easy

# Turn named parameters into arrays

min = (list...) ->
  curr = 0
  curr = x for x in list when x < curr
  curr

alert min a, b, c, d, e
var min = function() {
  var i, curr = 0, list = Array.prototype.apply(arguments);
  for (i = 0; i < list.length; i++) {
    if (list[i] < curr) {
      curr = list[i];
    }
  }
  return curr;
};
alert(min(a, b, c, d, e));

# Turn arrays into named parameters

date = (year, month, day) ->
  "#{ month }/#{ day }/#{ year }"

arr = [1999, 12, 31]
alert date arr...
var date = function(year, month, day) {
  return month + "/" + day + "/" + year;
};
var arr = [1999, 12, 31]
alert(date.apply(null, arr));

And a bunch of other crazy stuff

# Classes and inheritance

class Animal
  constructor: (@name) ->

  move: (meters) ->
    alert @name + " moved #{meters}m."

class Snake extends Animal
  move: ->
    alert "Slithering..."
    super 5

# Aliases

is, ==
inst, !=
not, !
and, &&
or, ||
true, yes, on
false, no, off
x unless y else z
@, this
of
in
a ** b
a // b
a %% b
===
!==
!
&&
||
true
false
!y ? x : z
this
in
//no true JS equivalent
Math.pow(a, b)
Math.floor(a / b)
(a % b + b) % b

Wait! I need decaf

# You can still embed plain JavaScript

if `x == y` then do z
if (x == y) {
    z();
}

Coffee goes with everything

# Editors and development tools

- Web Essentials for Visual Studio
- jsFiddle
- CoffeeScript.org
- Cassette
- Js2Coffee
- IntelliJ IDEA

# Add-ons and related projects

- IcedCoffeeScript
- CoffeeKup

CoffeeScript versus TypeScript: Which to Use?

# If you want static type checking and familiar tool support on Visual Studio choose TypeScript

# If you want a short learning curve from JavaScript choose TypeScript

# If you want more concise code and lots of syntactic sugar, choose CoffeeScript

# If you are coming from Ruby or Python, CoffeeScript is probably a better match

CoffeeScript: Only The Good Parts

By Bruno Dević

CoffeeScript: Only The Good Parts

  • 577