CoffeeScript – It's just Javascript – Variableistic



CoffeeScript – It's just Javascript – Variableistic

0 1


use-coffeescript

Presentation about switching to CoffeeScript

On Github mattdbridges / use-coffeescript

CoffeeScript

It's just Javascript

Created by Matt Bridges / @mattdbridges

Why?

Educate Improve Organize

Variableistic

# Never write `var` again!
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();

Conditionalism

mood = greatlyImproved if singing

if happy and knowsIt
  clapsHands()
  chaChaCha()
else
  showIt()

date = if friday then sue else jill
var date, mood;

if (singing) {
  mood = greatlyImproved;
}

if (happy && knowsIt) {
  clapsHands();
  chaChaCha();
} else {
  showIt();
}

date = friday ? sue : jill;

Functionalistic

square = (x) -> x * x
cube   = (x) -> square(x) * x
var cube, square;

square = function(x) {
  return x * x;
};

cube = function(x) {
  return square(x) * x;
};

A' Bounding

Account = (customer, cart) ->
  @customer = customer
  @cart = cart

  $('.shopping_cart').on 'click', (event) => # See the fat arrow!
    @customer.purchase @cart
var Account;

Account = function(customer, cart) {
  var _this = this; // Uses `_this` in later nested context
  this.customer = customer;
  this.cart = cart;
  return $('.shopping_cart').on('click', function(event) {
    return _this.customer.purchase(_this.cart);
  });
};

Existentialism

solipsism = true if mind? and not world?

speed = 0
speed ?= 15

footprints = yeti ? "bear"
var footprints, solipsism, speed;

if ((typeof mind !== "undefined" && mind !== null) &&
    (typeof world === "undefined" || world === null)) {
  solipsism = true;
}

speed = 0;

if (speed == null) {
  speed = 15;
}

footprints = typeof yeti !== "undefined" && yeti !== null ? yeti : "bear";

Expressionism

# The first ten global properties.

globals = (name for name of window)[0...10]
// You can make it prettier, but it's still more complicated
var globals, name;

globals = ((function() {
  var _results;
  _results = [];
  for (name in window) {
    _results.push(name);
  }
  return _results;
})()).slice(0, 10);

Conditionalism

volume = 10 if band isnt SpinalTap

letTheWildRumpusBegin() unless answer is no

if car.speed < limit then accelerate()

winner = yes if pick in [47, 92, 13]
var volume, winner;

if (band !== SpinalTap) {
  volume = 10;
}

if (answer !== false) { letTheWildRumpusBegin(); }

if (car.speed < limit) { accelerate(); }

// Coffeescript *always* converts == to ===
if (pick === 47 || pick === 92 || pick === 13) {
  winner = true;
}

Classification

class Animal
  constructor: (@name) ->

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

class Horse extends Animal
  move: ->
    alert "Galloping..."
    super 45

sam = new Animal "Sammy the Animal"
tom = new Horse  "Tommy the Palomino"

sam.move()
tom.move()
var Animal, Horse, sam, tom, _ref,
  __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

Animal = (function() {
  function Animal(name) {
    this.name = name;
  }

  Animal.prototype.move = function(meters) {
    return alert(this.name + (" moved " + meters + "m."));
  };

  return Animal;

})();

Horse = (function(_super) {
  __extends(Horse, _super);

  function Horse() {
    _ref = Horse.__super__.constructor.apply(this, arguments);
    return _ref;
  }

  Horse.prototype.move = function() {
    alert("Galloping...");
    return Horse.__super__.move.call(this, 45);
  };

  return Horse;

})(Animal);

sam = new Animal("Sammy the Animal");

tom = new Horse("Tommy the Palomino");

sam.move();

tom.move();;

Prototypical

String::dasherize = -> @replace /_/g, "-"
String.prototype.dasherize = function() {
  return this.replace(/_/g, "-");
};

Spec-Tactular

describe "makeSublist", ->

  beforeEach -> loadFixtures "application_makeSubList.html"

  it "should disable the child list", ->
    makeSublist "parentList", "childList", false, null
    $("#parentList").change()
    disabled = $("#childList").attr("disabled")
    expect(disabled).toBe "disabled"
describe("makeSublist", function(){

  beforeEach(function(){
    loadFixtures("application_makeSubList.html")
  });

  it("should disable the child", function(){
    makeSublist("parentList", "childList", false, null);
    $("#parentList").change();
    var disabled = $("#childList").attr("disabled")
    expect( disabled ).toBe("disabled");
  });

});

Other Awesome Reasons

  • String Interpolation
  • Chained comparisons (10 > 9 > 8 > 7 > etc….)
  • Multiline strings and HEREDocs
  • Block Regular Expressions ("//x" in Ruby)
  • Destructuring Assignment (" a, b, c = [1, 2, 3] ")
  • Splats…

Objections

1. Another Language

CoffeeScript is "Just Javascript". It's an abstraction to improve the features of javascript, not replace it.

2. Another Piece of Knowledge

CoffeeScript has been a default in Rails for a while. It has become an accepted part of the development process.

New developers we hire are likely familiar with it if they have been developing in Rails.

3. It writes crappy javascript

Stop worrying about Javascript. CoffeeScript is designed to write safe and working Javascript.

Yes, it does look crappy, but it looks ugly after precompiling anyway...

4. Debugging is hard

Yes, it is a bit tricky. It does, however, support source maps which makes this process much simpler.

Why?

1. Rails' Default

2. Hubot

DevOps will love you

3. It's Safe

Relatively speaking...

4. Writing Javascript Sucks

IMHO ;)

Go play with it

Thanks!

https://github.com/mattdbridges/use-coffeescript

0