CoffeeScript é uma pequena linguagem que compila para JavaScript. Por baixo de todas essas chaves e ponto-e-vírgulas inconvenientes, JavaScript sempre teve um lindo modelo de objeto em seu coração. CoffeeScript é uma tentativa de expor as partes boas de JavaScript de uma maneira simples.

A regra de ouro do CoffeeScript é: "É apenas JavaScript". O código compila para um JS equivalente, e não há uma interpretação em tempo de execução (runtime). Você pode usar qualquer biblioteca JavaScript existente com CoffeeScript sem problemas (e vice-versa). A saída compilada é legível e bem impressa, passa pelo JavaScript Lint sem advertências, funcionará em qualquer runtime JavaScript, e tende a executar tão ou mais rápido que o JavaScript equivalente escrito a mão.

Versão Mais Recente: 1.3.3

Traduzido para o português por Loop Infinito (@loopinfinito).

Visão Geral

CoffeeScript à esquerda, saída compilada de JavaScript à direita.

# Atribuições:
number   = 42
opposite = true

# Condições:
number = -42 if opposite

# Funções:
square = (x) -> x * x

# Arrays:
list = [1, 2, 3, 4, 5]

# Objetos:
math =
  root:   Math.sqrt
  square: square
  cube:   (x) -> x * square x

# Splats:
race = (winner, runners...) ->
  print winner, runners

# Teste de existência:
alert "I knew it!" if elvis?

# Compreensões de Arrays:
cubes = (math.cube num for num in list)
var cubes, list, math, num, number, opposite, race, square,
  __slice = [].slice;

number = 42;

opposite = true;

if (opposite) {
  number = -42;
}

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

list = [1, 2, 3, 4, 5];

math = {
  root: Math.sqrt,
  square: square,
  cube: function(x) {
    return x * square(x);
  }
};

race = function() {
  var runners, winner;
  winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
  return print(winner, runners);
};

if (typeof elvis !== "undefined" && elvis !== null) {
  alert("I knew it!");
}

cubes = (function() {
  var _i, _len, _results;
  _results = [];
  for (_i = 0, _len = list.length; _i < _len; _i++) {
    num = list[_i];
    _results.push(math.cube(num));
  }
  return _results;
})();
executar: cubes

Instalação

O próprio compilador CoffeeScript é escrito em CoffeeScript, usando o gerador de analisador (parser) Jison. A versão linha de comando coffee está disponível como um utilitário Node.js. O compilador entretanto, não depende do Node, e pode ser executado em qualquer ambiente JavaScript, ou no navegador (veja "Experimente CoffeeScript", acima).

Para instalar, primeiramente tenha certeza de que tem uma cópia da última versão estável do Node.js, e do npm (o Gerenciador de Pacotes do Node – Node Package Manager). Você então poderá instalar o CoffeeScript com o npm:

npm install -g coffee-script

(Deixe de fora o -g caso não queira instalar globalmente.)

Se preferir instalar a versão mais recente do CoffeeScript, você pode clonar o repositório do código fonte do CoffeeScript no GitHub, ou fazer o download do código fonte diretamente. Para instalar o compilador CoffeeScript para todo o sistema em /usr/local, abra o diretório e execute:

sudo bin/cake install

Uso

Depois de instalado, você deverá ter acesso ao comando coffee, que pode executar scripts, compilar arquivos .coffee para .js, e fornecer um REPL (Read-Eval-Print-Loop) interativo. O comando coffee aceita as seguintes opções:

-c, --compile Compila um script .coffee para um arquivo JavaScript .js com o mesmo nome.
-i, --interactive Inicia uma sessão interativa de CoffeeScript para execução de pequenos trechos. Idêntico ao chamar coffee sem argumentos.
-o, --output [DIR] Escreve todos os aquivos JavaScript compilados no diretório especificado. Use em conjunto com --compile ou --watch.
-j, --join [FILE] Antes de compilar, concatena todos os scrips juntos na mesma ordem em que forem passados, e os escreve no arquivo especificdo. Útil na construção de grandes projetos.
-w, --watch Observa os arquivos por modificações, reexecutando o comando especificdo quando qualquer arquivo for atualizado.
-p, --print Em vez de escrever o JavaScript como um arquivo, imprime diretamente na saída padrão (stdout).
-l, --lint Se o comando jsl (JavaScript Lint) está instalado, use-o para verificar a compilação de um arquivo CoffeeScript. (Conveniente em conjunto com
--watch)
-s, --stdio Passa o CoffeeScript para STDIN e recupera o JavaScript pela STDOUT. Bom para uso com processos escritos em outras linguagens. Por exemplo:
cat src/cake.coffee | coffee -sc
-e, --eval Compila e imprime um pequeno fragmento de CoffeeScript diretamente da linha de comando. Por exemplo:
coffee -e "console.log num for num in [10..1]"
-r, --require Carrega uma biblioteca antes de compilar ou executar seu script. Pode ser usado para ligar algo ao compilador (para adicionar notificações Growl, por exemplo).
-b, --bare Compila o JavaScript sem a função de segurança de alto nível.
-t, --tokens Em vez de realizar a análise sintática (parse) do CoffeeScript, apenas realiza a analise léxica e imprime o fluxo de tokens: [IDENTIFIER square] [ASSIGN =] [PARAM_START (] ...
-n, --nodes Em vez de compilar o CoffeeScript, apenas realiza as análises léxica e sintática, e imprime a árvore sintática:
Expressions
  Assign
    Value "square"
    Code "x"
      Op *
        Value "x"
        Value "x"
--nodejs O executável node tem algumas opções úteis que você pode especificar, como --debug, --debug-brk e --max-stack-size. Use esta flag para passar as opções diretamente ao Node.js.

Exemplos:

Referência da Linguagem

Esta referência está estruturada de maneira que possa ser lida de cima para baixo, se desejar. Ao decorrer do documento, as seções usam idéias e sintaxes anteriormente introduzidas. É necessário ter familiaridade com JavaScript. Em todos os exemplos seguintes, o código CoffeeScript é fornecido ao lado esquerdo, e a compilação direta para JavaScript está ao lado direito.

Muitos dos exemplos podem ser executados (os que fazem sentido), pressionando o botão executar à direita, e pode ser carregado no console "Experimente CoffeeScript" pressionando o botão carregar do lado esquerdo.

Primeiramente, o básico: CoffeeScript usa espaços em branco para delimitar blocos de código. Você não precisa usar ponto-e-vígulas ; ao término de uma expressão, terminar a linha terá o mesmo resultado (embora ainda seja possível utilizar ponto-e-vírgula para delimitar várias expressões em uma mesma linha). Em vez de usar chaves { } para agrupar blocos de código em funções, if, switch, e try/catch, use indentação.

Você não precisa usar parênteses para invocar uma função se você estiver passando argumentos. A chamada agrupa implicitamente até o fim da linha ou da expressão de bloco.
console.log sys.inspect objectconsole.log(sys.inspect(object));

Funções Funções são definidas por uma lista de parâmetros opcionais entre parênteses, uma seta, e o corpo da função. A função vazia parece assim: ->

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;
};
carregar
executar: cube(5)

Funções também podem ter valores padrão para argumentos. Sobrescreva o valor padrão passando um argumento não nulo.

fill = (container, liquid = "coffee") ->
  "Filling the #{container} with #{liquid}..."






var fill;

fill = function(container, liquid) {
  if (liquid == null) {
    liquid = "coffee";
  }
  return "Filling the " + container + " with " + liquid + "...";
};
carregar
executar: fill("cup")

Objetos e Arrays Os literias de CoffeeScript para objetos e arrays se parecem bastante com seus primos JavaScript. Quando cada propriedade é listada em sua própria linha, as vírgulas são opcionais. Objetos devem ser criados usando indentação em vez de chaves explícitas, similar ao YAML.

song = ["do", "re", "mi", "fa", "so"]

singers = {Jagger: "Rock", Elvis: "Roll"}

bitlist = [
  1, 0, 1
  0, 0, 1
  1, 1, 0
]

kids =
  brother:
    name: "Max"
    age:  11
  sister:
    name: "Ida"
    age:  9


var bitlist, kids, singers, song;

song = ["do", "re", "mi", "fa", "so"];

singers = {
  Jagger: "Rock",
  Elvis: "Roll"
};

bitlist = [1, 0, 1, 0, 0, 1, 1, 1, 0];

kids = {
  brother: {
    name: "Max",
    age: 11
  },
  sister: {
    name: "Ida",
    age: 9
  }
};
carregar
executar: song.join(" ... ")

Em JavaScript, você não pode usar palavras reservadas, como class, como propriedades de um objeto, sem envolvê-las com aspas como strings. CoffeeScript reconhece palavras reservadas usadas como chave (key) em um objeto e coloca aspas nelas para você, então você não precisa se preocupar com isso (por exemplo, quando usando jQuery).

$('.account').attr class: 'active'

log object.class


$('.account').attr({
  "class": 'active'
});

log(object["class"]);
carregar

Escopo Léxico e Segurança de Variáveis O compilador CoffeeScript tem o cuidado de se certificar que todas as suas variáveis estão propriamente declaradas dentro de um escopo léxico — você mesmo nunca precisa escrever var.

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();
carregar
executar: inner

Note como todas as declarações de variável foram colocadas no começo do escopo mais próximo, a primeira vez que elas aparecem. outer não está declarada dentro da função, porque ela já está no escopo; inner dentro da função, por outro lado, não deve ser capaz de mudar o valor da variável externa de mesmo nome, e portanto tem uma própria declaração.

Este comportamento é efetivamente idêntico ao escopo de Ruby para variáveis locais. Pelo fato de você não ter acesso direto à palavra-chave var, é impossível esconder uma variável externa de propósito, você deve apenas se referir a ela. Então tenha cuidado com o reuso de um nome de variável externa acidentalmente, principalmente se você estiver escrevendo uma função profundamente aninhada.

Embora suprimida nesta documentação para maior clareza, toda saída CoffeeScript é empacotada em uma função anônima: (function(){ ... })(); Este empacotador seguro, combinado com a geração automática da palavra-chave var, faz com que seja extremamente difícil de poluir os espaços de nomes (namespaces) globais por acidente.

Se você quiser criar variáveis de nível superior para outros scripts usarem, anexe-as como propriedades em window, ou no objeto exports em CommonJS. O operador existencial (mostrado abaixo), fornece a você uma forma confiável de descobrir onde adicioná-las; se você quiser as duas coisas (CommonJS e o navegador): exports ? this

If, Else, Unless, e Atribuição Condicional Declarações If/else podem ser escritas sem o uso de parênteses e chaves. Assim como funções e outras expressões de bloco, condicionais multi-linha são delimitados por indentação. Também existe uma forma pós-fixa, com o if ou unless ao final.

CoffeeScript pode compilar declarações if para expressões JavaScript, usando o operador ternário quando possível, e blocos de chaves caso contrário. Não existe declaração ternária explícita em CoffeeScript — você simplesmente usa uma declaração if normal em uma mesma linha.

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;
carregar

Splats... O objeto de argumentos de JavaScript é uma maneira útil de trabalhar com funções que aceitam um número variado de argumentos. CoffeeScript fornece splats ..., tanto para definições de função quanto para invocações, fazendo com que o número variável de argumentos seja um pouco mais saboroso.

gold = silver = rest = "unknown"

awardMedals = (first, second, others...) ->
  gold   = first
  silver = second
  rest   = others

contenders = [
  "Michael Phelps"
  "Liu Xiang"
  "Yao Ming"
  "Allyson Felix"
  "Shawn Johnson"
  "Roman Sebrle"
  "Guo Jingjing"
  "Tyson Gay"
  "Asafa Powell"
  "Usain Bolt"
]

awardMedals contenders...

alert "Gold: " + gold
alert "Silver: " + silver
alert "The Field: " + rest


var awardMedals, contenders, gold, rest, silver,
  __slice = [].slice;

gold = silver = rest = "unknown";

awardMedals = function() {
  var first, others, second;
  first = arguments[0], second = arguments[1], others = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
  gold = first;
  silver = second;
  return rest = others;
};

contenders = ["Michael Phelps", "Liu Xiang", "Yao Ming", "Allyson Felix", "Shawn Johnson", "Roman Sebrle", "Guo Jingjing", "Tyson Gay", "Asafa Powell", "Usain Bolt"];

awardMedals.apply(null, contenders);

alert("Gold: " + gold);

alert("Silver: " + silver);

alert("The Field: " + rest);
carregar
executar

Laços e Compreensões de Listas A maioria dos laços (loops) que você escreverá em CoffeeScript serão compreensões de listas (list comprehensions) em arrays, objetos, e intervalos (ranges). Compreensões de listas substituem (e compilam para) laços for, com cláusulas guard opcionais e o valor atual do índice do array. Diferente de laços, as compreensões são expressões, e podem ser retornadas e atribuídas.

# Coma o almoço
eat food for food in ['toast', 'cheese', 'wine']

# Jantar fino de cinco pratos
courses = ['greens', 'caviar', 'truffles', 'roast', 'cake']
menu i + 1, dish for dish, i in courses

# Refeição saudável
foods = ['broccoli', 'spinach', 'chocolate']
eat food for food in foods when food isnt 'chocolate'
var courses, dish, food, foods, i, _i, _j, _k, _len, _len1, _len2, _ref;

_ref = ['toast', 'cheese', 'wine'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  food = _ref[_i];
  eat(food);
}

courses = ['greens', 'caviar', 'truffles', 'roast', 'cake'];

for (i = _j = 0, _len1 = courses.length; _j < _len1; i = ++_j) {
  dish = courses[i];
  menu(i + 1, dish);
}

foods = ['broccoli', 'spinach', 'chocolate'];

for (_k = 0, _len2 = foods.length; _k < _len2; _k++) {
  food = foods[_k];
  if (food !== 'chocolate') {
    eat(food);
  }
}
carregar

Compreensões devem ser capazes de lidar com a maioria dos casos onde você de outra maneira usaria um laço normal, each/forEach, map, ou select/filter, por exemplo: shortNames = (name for name in list when name.length < 5)
Se você sabe o começa e termina o laço, ou gostaria de percorrer o laço com incrementos de tamanho fixo, você pode usar um intervalo (range) para especificar o começo e o fim das suas compreensões.

countdown = (num for num in [10..1])

var countdown, num;

countdown = (function() {
  var _i, _results;
  _results = [];
  for (num = _i = 10; _i >= 1; num = --_i) {
    _results.push(num);
  }
  return _results;
})();
carregar
executar: countdown

Peceba que, pelo fato de estarmos atribuindo o valor das compreensões de lista (list comprehension) a uma variável no exemplo acima, CoffeeScript coleta o resultado de cada iteração em um array. Às vezes funções terminam com laços que servem apenas para rodar no contexto da própria função. Tenha cuidado para não retornar acidentalmente os resultados da compreensão, nestes casos apenas adicione um valor de retorno significativo — como true — ou null, ao final da sua função.

Para percorrer uma compreensão de intervalo em passos de tamanho fixo, use by, por exemplo:
pares = (x for x in [0..10] by 2)

Compreensões também podem ser usadas para iterar sobre as chaves (key) e valores (value) em um objeto. Use of para sinalizar a compreensão sobre as propriedades de um objeto, em vez dos valores em um array.

yearsOld = max: 10, ida: 9, tim: 11

ages = for child, age of yearsOld
  "#{child} is #{age}"
var age, ages, child, yearsOld;

yearsOld = {
  max: 10,
  ida: 9,
  tim: 11
};

ages = (function() {
  var _results;
  _results = [];
  for (child in yearsOld) {
    age = yearsOld[child];
    _results.push("" + child + " is " + age);
  }
  return _results;
})();
carregar
executar: ages.join(", ")

Se desejar iterar somente sobre as chaves (keys) que são definidas no próprio objeto adicione uma verificação hasOwnProperty ,para evitar propriedades que possam ter sido herdadas do protótipo use
for own key, value of object

O único laço de baixo nível que CoffeeScript fornece é o laço while. A principal diferença de JavaScript é que o laço while pode ser usado como uma expressão, retornando um array contendo o resultado de cada iteração atravéz do laço.

# Econ 101
if this.studyingEconomics
  buy()  while supply > demand
  sell() until supply > demand

# Rima de berçário
num = 6
lyrics = while num -= 1
  "#{num} little monkeys, jumping on the bed.
    One fell out and bumped his head."
var lyrics, num;

if (this.studyingEconomics) {
  while (supply > demand) {
    buy();
  }
  while (!(supply > demand)) {
    sell();
  }
}

num = 6;

lyrics = (function() {
  var _results;
  _results = [];
  while (num -= 1) {
    _results.push("" + num + " little monkeys, jumping on the bed.    One fell out and bumped his head.");
  }
  return _results;
})();
carregar
executar: lyrics.join("\n")

Para legibilidade, a palavra-chave until é equivalente a while not, e a palavra-chave loop é equivalente a while true.

Quando usando um laço JavaScript para gerar funções, é comum inserir um invólucro (wrapper) a fim de garantir que as variáveis do laço estejam corretamente fechadas, e todas as funções geradas não compartilhem apenas os valores finais. CoffeeScript fornece a palavra-chave do, que invoca imediatamente uma função passada com seus respectivos argumentos.

for filename in list
  do (filename) ->
    fs.readFile filename, (err, contents) ->
      compile filename, contents.toString()
var filename, _fn, _i, _len;

_fn = function(filename) {
  return fs.readFile(filename, function(err, contents) {
    return compile(filename, contents.toString());
  });
};
for (_i = 0, _len = list.length; _i < _len; _i++) {
  filename = list[_i];
  _fn(filename);
}
carregar

Fatiamento e Substituição com Intervalos de Arrays Intervalos (ranges) também podem ser usados para extrair fatias (slices) de arrays. Com dois pontos (3..6), o intervalo é inclusivo (3, 4, 5, 6); Com trêz pontos (3...6), o intervalo exclui o final (3, 4, 5). Índices de fatias têm padrões úteis. Se o primeiro índice for omitido, terá o mesmo efeito que ter sido setado com 0, e se o segundo índice for omitido, terá o mesmo efeito que ter sido setado com o tamanho do array.

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]

start   = numbers[0..2]

middle  = numbers[3...6]

end     = numbers[6..]

copy    = numbers[..]
var copy, end, middle, numbers, start;

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];

start = numbers.slice(0, 3);

middle = numbers.slice(3, 6);

end = numbers.slice(6);

copy = numbers.slice(0);
carregar
executar: middle

A mesma sintaxe pode ser usada com atribuição para substituir um segmento de um array com novos valores, "emendando-o" (splice).

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

numbers[3..6] = [-3, -4, -5, -6]



 
var numbers, _ref;

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

[].splice.apply(numbers, [3, 4].concat(_ref = [-3, -4, -5, -6])), _ref;
carregar
executar: numbers

Perceba que strings JavaScript são imutáveis, e não podem ser "emendadas".

Tudo é uma Expressão (pelo menos, o tanto quanto possível) Você deve ter notado que apesar de não termos adicionado declarações de retorno às funções CoffeeScript, mesmo assim elas retornam seu valor final. O compilador CoffeeScript tenta se assegurar que todas as declarações na linguagem possam ser usadas como expressões. Veja como o return acaba indo parar no final de cada ramo possível de execução na função abaixo.

grade = (student) ->
  if student.excellentWork
    "A+"
  else if student.okayStuff
    if student.triedHard then "B" else "B-"
  else
    "C"

eldest = if 24 > 21 then "Liz" else "Ike"
var eldest, grade;

grade = function(student) {
  if (student.excellentWork) {
    return "A+";
  } else if (student.okayStuff) {
    if (student.triedHard) {
      return "B";
    } else {
      return "B-";
    }
  } else {
    return "C";
  }
};

eldest = 24 > 21 ? "Liz" : "Ike";
carregar
executar: eldest

Apesar de funções sempre retornarem seu valor final, é possível e encorajado retornar o mais depressa possível de um corpo de função escrevendo explicitamente return (return value).

Pelo fato das declarações de variável ocorrerem no topo do escopo, pode ser usado atribuição dentro de expressões, até mesmo para variáveis que não foram vistas antes:

six = (one = 1) + (two = 2) + (three = 3)


var one, six, three, two;

six = (one = 1) + (two = 2) + (three = 3);
carregar
executar: six

Coisas que poderiam, de outra maneira, ser declarações em JavaScript quando usadas como uma parte de uma expressão em CoffeeScript, são convertidas em expressões agrupando-as em um bloco. Isto permite a você fazer coisas úteis, como atribuir o resultado de uma compreensão de lista a uma variável:

# The first ten global properties.

globals = (name for name of window)[0...10]
var globals, name;

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

Bem como coisas bobas, como passar uma declaração try/catch diretamente em uma chamada de função:

alert(
  try
    nonexistent / undefined
  catch error
    "And the error is ... #{error}"
)

alert((function() {
  try {
    return nonexistent / void 0;
  } catch (error) {
    return "And the error is ... " + error;
  }
})());
carregar
executar

Há um punhado de instruções em JavaScript que não podem ser verdadeiramente convertidas em expressões, como break, continue, e return. Se você faz uso delas dentro de um bloco de código, CoffeeScript não tentará realizar a conversão.

Operadores e Aliases Pelo fato de o operador == frequentemente causar coerção indesejável, é intransitivo, e tem um significado diferente do que em outras linguagens, CoffeeScript compila == para ===, e != para !==. Além disso, is compila para ===, e isnt para !==.

Você pode usar not como um apelido (alias) para !.

Por lógica, and compila para &&, e or para ||.

Em vez de uma nova linha ou ponto-e-vígula, then pode ser usado para separar condições de expressões, em instuções while, if/else, e switch/when.

Como em YAML, on e yes são o mesmo booleano true, enquanto off e no são o booleano false.

unless pode ser usado como o inverso de if.

Como um atalho para this.propriedade, você pode usar @propriedade.

Você pode usar in para testar a presença em array, e of para testar a presença de chave (key) de objeto JavaScript.

Tudo junto agora:

CoffeeScriptJavaScript
is===
isnt!==
not!
and&&
or||
true, yes, ontrue
false, no, offfalse
@, thisthis
ofin
insem equivalente JS
launch() if ignition is on

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]

print inspect "My name is #{@name}"
var volume, winner;

if (ignition === true) {
  launch();
}

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

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

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

if (pick === 47 || pick === 92 || pick === 13) {
  winner = true;
}

print(inspect("My name is " + this.name));
carregar

O Operador Existencial É um pouco difícil de verificar a existência de uma variável em JavaScript. if (variavel) ... chega perto, mais falha para zero (0), string vazia ("") e falso (false). O operador existencial de CoffeeScript ? retorna verdadeiro a menos que a variável seja null ou undefined, o que a faz análoga ao nil? de Ruby.

Ele também pode ser usado para atribuição condicional com mais segurança que ||= fornece, para casos onde você tenha que lidar com números ou strings.

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";
carregar
executar: footprints

A variante do operador existencial ?. pode ser usada para absorver referências nulas em uma cadeia de propriedades. Use-o no lugar do operador . nos casos onde o valor base pode ser null ou undefined. Se todas a propriedades existem então você terá o resultado esperado, se a cadeia estiver quebrada, undefined é retornado em vez de TypeError que seria o normal.

zip = lottery.drawWinner?().address?.zipcode
var zip, _ref;

zip = typeof lottery.drawWinner === "function" ? (_ref = lottery.drawWinner().address) != null ? _ref.zipcode : void 0 : void 0;
carregar

Absorver valores nulos (null) é similar ao andand gem de Ruby, e ao safe navigation operator em Groovy.

Classes, Herança, and Superclasses A herança prototipada de JavaScript sempre foi um pouco confusa, com toda uma árvore genealógica de bibliotecas que fornecem uma sintaxe mais clara para herança clássica no topo dos protótipos JavaScript: Base2, Prototype.js, JS.Class, etc. As bibliotecas oferecem um "açúcar sintático" (syntatic sugar), e a herança padrão seria completamente utilizável se não fosse por umas pequenas exceções: é estranho chamar a superclasse (a implementação do protótipo do objeto da função atual), e é estranho utilizar a cadeia de protótipo corretamente.

Em vez de anexar funções a um protótipo repetidamente, CoffeeScript fornece uma estrutura básica class que permite a você nomear sua classe, setar a superclasse, atribuir propriedades de protótipo, e definir o construtor em uma única expressão atribuível.

Funções construtoras são nomeadas, para melhor apoiar os rastreamentos úteis de pilha (stack trace. Na primeira classe no exemplo abaixo, this.constructor.name is "Animal".

class Animal
  constructor: (@name) ->

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

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

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

sam = new Snake "Sammy the Python"
tom = new Horse "Tommy the Palomino"

sam.move()
tom.move()




var Animal, Horse, Snake, sam, tom,
  __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;

})();

Snake = (function(_super) {

  __extends(Snake, _super);

  function Snake() {
    return Snake.__super__.constructor.apply(this, arguments);
  }

  Snake.prototype.move = function() {
    alert("Slithering...");
    return Snake.__super__.move.call(this, 5);
  };

  return Snake;

})(Animal);

Horse = (function(_super) {

  __extends(Horse, _super);

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

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

  return Horse;

})(Animal);

sam = new Snake("Sammy the Python");

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

sam.move();

tom.move();
carregar
executar

Se estruturar seus protótipos da maneira clássica não é sua praia, CoffeeScript fornece umas conveniências de baixo nível. O operador extends ajuda com a configuração de protótipo adequada, e pode ser usado para criar uma cadeia de herança entre qualquer par de funções construtoras; :: lhe dá acesso rápido a uma propriedade de objeto; e super() é convertido em uma chamada direta ao método com o mesmo nome do seu ancestral (superclasse).

String::dasherize = ->
  this.replace /_/g, "-"

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

Finalmente, definições de classe são blocos de código executável, o que faz com que as possibilidades de metaprogramação se tornem interessantes. Por causa do contexto de uma definição de classe, this é o próprio objeto de classe (a função construtora), você pode atribuir propriedades estáticas usando
@property: value, e chamar funções definidas em classes pai: @attr 'title', type: 'text'.

Atribuição de Troca Para fazer com que a extração de valores de arrays e objetos complexos mais conveniente, CoffeeScript implementa a sintaxe destructuring assignment proposta pelo ECMAScript Harmony. Quando você atribui um array ou objeto para um valor, CoffeeScript se fragmenta e combina os dois lados, atribuindo os valores da direita às variáveis da esquerda. De maneira mais simples, pode ser usado para atribuição paralela:

theBait   = 1000
theSwitch = 0

[theBait, theSwitch] = [theSwitch, theBait]




 
var theBait, theSwitch, _ref;

theBait = 1000;

theSwitch = 0;

_ref = [theSwitch, theBait], theBait = _ref[0], theSwitch = _ref[1];
carregar
executar: theBait

Mas também é bastante útil para lidar com funções que retornam multiplos valores.

weatherReport = (location) ->
  # Make an Ajax request to fetch the weather...
  [location, 72, "Mostly Sunny"]

[city, temp, forecast] = weatherReport "Berkeley, CA"




var city, forecast, temp, weatherReport, _ref;

weatherReport = function(location) {
  return [location, 72, "Mostly Sunny"];
};

_ref = weatherReport("Berkeley, CA"), city = _ref[0], temp = _ref[1], forecast = _ref[2];
carregar
executar: forecast

Atribuição de troca (Destructuring assignment) pode ser usada com qualquer profundidade de array ou aninhamento de objeto, para ajudar a extrair propriedades profundamente aninhadas.

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



var city, futurists, name, street, _ref, _ref1;

futurists = {
  sculptor: "Umberto Boccioni",
  painter: "Vladimir Burliuk",
  poet: {
    name: "F.T. Marinetti",
    address: ["Via Roma 42R", "Bellagio, Italy 22021"]
  }
};

_ref = futurists.poet, name = _ref.name, (_ref1 = _ref.address, street = _ref1[0], city = _ref1[1]);
carregar
executar: name + " - " + street

Atribuição de troca pode até ser combinada com splats.

tag = "<impossible>"

[open, contents..., close] = tag.split("")






var close, contents, open, tag, _i, _ref,
  __slice = [].slice;

tag = "<impossible>";

_ref = tag.split(""), open = _ref[0], contents = 3 <= _ref.length ? __slice.call(_ref, 1, _i = _ref.length - 1) : (_i = 1, []), close = _ref[_i++];
carregar
executar: contents.join("")

Vinculação de Funções Em JavaScript, a palavra-chave this é dinamicamente "escopada" para que o objeto seja referente a função da qual ele está vinculado. Se você passar uma função como um callback ou vinculá-la a um objeto diferente, o valor original de this será perdido. Se você não está familiarizado com este comportamento, este artigo fornece uma boa visão dessas peculiaridades.

A seta dupla => pode ser usada tanto para definir uma função quanto para vinculá-la ao valor atual de this no lugar certo. Isto é útil quando usamos bibliotecas baseadas em callbacks como Prototype ou jQuery, para criar funções iteradoras para passar para each, ou para funções manipuladoras de eventos usarem com bind. Funções criadas com a seta dupla são capazes de acessar propriedades do this onde elas são definidas.

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

  $('.shopping_cart').bind 'click', (event) =>
    @customer.purchase @cart
var Account;

Account = function(customer, cart) {
  var _this = this;
  this.customer = customer;
  this.cart = cart;
  return $('.shopping_cart').bind('click', function(event) {
    return _this.customer.purchase(_this.cart);
  });
};
carregar

Se tivéssemos usado -> no callback acima, @customer teria se referido à propriedade "customer" indefinida do elemento DOM, e tentado chamar purchase() nela teria gerado uma exceção.

Quando usados em uma definição de classe, métodos declarados com a seta dupla serão automaticamente vinculados a cada instância da classe quando a instância for construída.

JavaScript Embutido Provavelmente, você nunca precisará utilizar isso, mas se você precisar intercalar fragmentos de JavaScript dentro do seu CoffeeScript, pode utilizar crases para incluí-los diretamente.

hi = `function() {
  return [document.title, "Hello JavaScript"].join(": ");
}`



var hi;

hi = function() {
  return [document.title, "Hello JavaScript"].join(": ");
};
carregar
executar: hi()

Switch/When/Else Instruções switch em JavaScript são um pouco inconvenientes. Você se lembrar de incluir um break ao final de toda instrução case para evitar de cair no case padrão (default) acidentalmente. CoffeeScript impede essa caída acidental, e pode converter o switch em expressões retornáveis e atribuíveis. O formato é: codição switch, cláusulas when e cláusulas else como o case padrão.

Como em Ruby, instruções switch em CoffeeScript podem ter multiplos valores para cada cláusula when. Se qualquer um dos valores casar, a cláusula é executada.

switch day
  when "Mon" then go work
  when "Tue" then go relax
  when "Thu" then go iceFishing
  when "Fri", "Sat"
    if day is bingoDay
      go bingo
      go dancing
  when "Sun" then go church
  else go work
switch (day) {
  case "Mon":
    go(work);
    break;
  case "Tue":
    go(relax);
    break;
  case "Thu":
    go(iceFishing);
    break;
  case "Fri":
  case "Sat":
    if (day === bingoDay) {
      go(bingo);
      go(dancing);
    }
    break;
  case "Sun":
    go(church);
    break;
  default:
    go(work);
}
carregar

Try/Catch/Finally Instruções try/catch são as mesmas do JavaScript (contudo, funcionam como expressões).

try
  allHellBreaksLoose()
  catsAndDogsLivingTogether()
catch error
  print error
finally
  cleanUp()

try {
  allHellBreaksLoose();
  catsAndDogsLivingTogether();
} catch (error) {
  print(error);
} finally {
  cleanUp();
}
carregar

Comparações em Cadeia CoffeeScript pega emprestado as comparações em cadeia (em inglês) de Python — facilitando testar se um valor está dentro de um determinado intervalo.

cholesterol = 127

healthy = 200 > cholesterol > 60


var cholesterol, healthy;

cholesterol = 127;

healthy = (200 > cholesterol && cholesterol > 60);
carregar
executar: healthy

Interpolação de String, Blocos de String e Blocos de Comentário A interpolação de string no estilo Ruby está incluída no CoffeeScript. Strings de aspas duplas permitem valores interpolados usando #{ ... }, e aspas simples são apenas strings literais.

author = "Wittgenstein"
quote  = "A picture is a fact. -- #{ author }"

sentence = "#{ 22 / 7 } is a decent approximation of π"





var author, quote, sentence;

author = "Wittgenstein";

quote = "A picture is a fact. -- " + author;

sentence = "" + (22 / 7) + " is a decent approximation of π";
carregar
executar: sentence

Strings multi-linha são permitidas em CoffeeScript.

mobyDick = "Call me Ishmael. Some years ago --
 never mind how long precisely -- having little
 or no money in my purse, and nothing particular
 to interest me on shore, I thought I would sail
 about a little and see the watery part of the
 world..."


var mobyDick;

mobyDick = "Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world...";
carregar
executar: mobyDick

Blocos de strings podem ser usadas para armazenar texto formatado ou indentado (ou, se você apenas não gosta de escapar aspas e apóstrofos). O nível de indentação que começa o bloco é mantido do começo ao fim, então você pode manter tudo alinhado com o corpo do seu código.

html = """
       <strong>
         cup of coffeescript
       </strong>
       """
       
var html;

html = "<strong>\n  cup of coffeescript\n</strong>";
carregar
executar: html

Blocos de strings de aspas duplas, assim como qualquer string de aspas duplas, também permitem interpolação.

Às vezes você pode querer passar um bloco de comentário para o JavaScript gerado. Por exemplo, quando você precisa embutir um cabeçalho de licenciamento no topo de um arquivo. Comentários em bloco, que refletem a sintaxe de strings em bloco, são preservados no código gerado.

###
CoffeeScript Compiler v1.3.3
Released under the MIT License
###


/*
CoffeeScript Compiler v1.3.3
Released under the MIT License
*/


carregar

Blocos de Expressões Regulares De forma similar aos blocos de strings e comentários, CoffeeScript também suporta blocos de expressões regulares (regexes) — expressões regulares extendidas que ignoram espaços em branco internos e que podem conter comentários e interpolação. Modelado de forma similiar ao modificador /x de Perl, os blocos de expressão regular do CoffeeScript são delimitados por /// e fazem com que as expressões regulares se tornem legíveis. Veja o exemplo abaixo:

OPERATOR = /// ^ (
  ?: [-=]>             # function
   | [-+*/%<>&|^!?=]=  # compound assign / compare
   | >>>=?             # zero-fill right shift
   | ([-+:])\1         # doubles
   | ([&|<>])\2=?      # logic / shift
   | \?\.              # soak access
   | \.{2,3}           # range or splat
) ///


var OPERATOR;

OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;
carregar

Cake, e Cakefiles

CoffeeScript inclui um sistema de construção (build system) muito simples parecido com o Make e o Rake. Naturalmente, ele é chamado de Cake, e é usado pelas tarefas que constroem e testam a própria linguagem CoffeeScript. Tarefas (tasks) são definidas em um arquivo chamado de Cakefile, e podem ser invocadas chamando cake [tarefa] de dentro do diretório. Para imprimir uma lista de todas as tarefas e opções, basta digitar cake.

Definições de tarefas são escritas em CoffeeScript, assim você pode incluir código arbitrário em seu Cakefile. Defina uma tarefa com um nome, uma descrição, e a função que será invocada quando a tafera for executada. Se sua tarefa tem uma opção de linha de comando, você pode definir a opção com flags curtos e longos, e ela ficará disponível on objeto options. Abaixo há uma tarefa que usa a API Node.js para reconstruir o analizador sintático do CoffeeScript:

fs = require 'fs'

option '-o', '--output [DIR]', 'directory for compiled code'

task 'build:parser', 'rebuild the Jison parser', (options) ->
  require 'jison'
  code = require('./lib/grammar').parser.generate()
  dir  = options.output or 'lib'
  fs.writeFile "#{dir}/parser.js", code
var fs;

fs = require('fs');

option('-o', '--output [DIR]', 'directory for compiled code');

task('build:parser', 'rebuild the Jison parser', function(options) {
  var code, dir;
  require('jison');
  code = require('./lib/grammar').parser.generate();
  dir = options.output || 'lib';
  return fs.writeFile("" + dir + "/parser.js", code);
});
carregar

Se você precisa executar uma tarefa antes de outra — por exemplo, rodando build antes de test, você pode utilizar a função invoke: invoke 'build'. Tarefas cake são uma maneira minimalista de expor suas funções CoffeeScript na linha de comando, então não nada muito extravagante. Se você precisa de dependências, ou de callbacks assíncronos, é melhor você mesmo colocá-los em seu código — e não a tarefa cake.

Tags de script "text/coffeescript"

Mesmo não sendo recomendável para uso em produção, códigos CoffeeScript podem ser incluídos diretamente no navegador usando tags <script type="text/coffeescript">. O código fonte inclui uma versão compactada e minificada do compilador (Faça o download da versão atual, 39k em gzip) como em extras/coffee-script.js. Inclua este arquivo na página com as tags inline do CoffeeScript, e ele irá compilar e validar os scripts – nesta ordem.

Na verdade, o pequeno script que executa "Experimente CoffeeScript" acima, assim como o jQuery do menu, é implementado exatamente dessa maneira. Abra o código fonte e olhe para o final da página para ver o exemplo. Incluir o script também lhe dá acesso ao CoffeeScript.compile() assim você pode abrir o Firebug – ou o Inspector no Chrome – e tentar compilar algumas strings.

As advertências comuns sobre a aplicação de CoffeeScript — seus scripts inline serão executados dentro de um ambiente separado, então se você quiser expor variáveis ou funções globais, vincule-as ao objeto window.

Livros

Existem vários meios excelentes para ajudá-lo a começar com CoffeeScript, alguns deles estão disponíveis online gratuitamente.

Screencasts

Exemplos

A melhor lista de exemplos CoffeeScript open-source pode ser encontrada no GitHub. Mais alguns:

Recursos

Web Chat (IRC)

Ajuda rápida e conselhos podem ser encontrados no canal de IRC CoffeeScript. Entre em #coffeescript em irc.freenode.net, ou clique no botão abaixo para abrir uma sessão webchat nesta página.

Log de mudanças

1.3.3 15 mai 2012

1.3.1 10 abr 2012

1.2.0 18 dez 2011

1.1.3 8 nov 2011

1.1.2 August 4, 2011 Correção na formatação de comentários de bloco, compilação de ?=, chamadas implícitas contra estruturas de controle, invocação implícita de um bloco try/catch, argumentos variádicos vazando para o escopo local, número de linha de erro de sintaxe seguido de heregex, acesso a propriedade em números literais entre parênteses, vincula métodos de classes e super com nomes reservados, reformulação do REPL, ponto-e-vírgula consecutivos compilados, comentários em bloco de objetos chamados de forma implícita e um bug no Chrome.

1.1.1 May 10, 2011 Correção de bug em classes com funções construtoras externas, ver Issue #1182.

1.1.0 1 mai 2011 Quando executado pelo coffee, process.argv e similares agora informam coffee ao invés de node. Melhor compatibilidade com módulos no Node.js 0.4.x. A saída do REPL é agora colorida, como no Node.js. Obrigatório dar um nome aos CoffeeScripts concatenados quando usada a flag --join. Correção na análise léxica de divisão composta =/ como regex. Todas as tags text/coffeescript agora devem ser executadas na ordem que são incluídas. Corrigido um problema ao estender subclasses usando funções construtoras externas. Corrigido problema de velocidade exponencial com chamadas de funções em cadeias muito grandes. Globais não vazam mais no REPL CoffeeScript. Parâmetros splatted são declarados localmente para a função.

1.0.1 31 jan 2011 Corrigido bug no analizador léxico com identificadores Unicode. REPL atualizado para compatibilidade com Node.js 0.3.7. Corrigido bug na requisição de caminhos relativos no REPL. return e return undefined finais agora são otimizados. O módulo util agora não é mais usado devido a compatibilidade com Node.js 0.2.5. Corrigido um caso onde um return condicional poderia disparar o case padrão. Otimização de objetos vazios na atribuição de desestruturação.

1.0.0 24 dez 2010 Laços (loops) CoffeeScript não tentam mais preservar o escopo do bloco quando funções estão sendo geradas dentro do corpo do laço. Caso necessário, você pode usar a palavra-chave do para criar um wrapper de maneira fácil. Adicionada a flag --nodejs para passar opções diretamente ao executável node. Melhor comportamento no uso de declarações dentro de expressões. Corrigido slicing inclusivo através de -1, para todos os navegadores, e splicing com expressões como pontos de parada.

0.9.6 6 dez 2010 REPL agora formata de forma correta stacktraces, e continua rodando entre exceções assíncronas. Usando --watch agora imprime timestamps quandos os arquivos são compilados. Corrigido bug que deixava variáveis vazar dentro de plucked closures-loops. Construtores agora mantêm o seu local de declaração dentro do corpo da classe. Chaves de objetos dinâmicos foram removidas. Classes aninhadas agora são suportadas. Corrige contexto de execução para funções splats nuas (naked splatted functions). Correção de bug para inversão de comparação em cadeia. Instanciação de classes em cadeia agora funcionam de forma correta com splats.

0.9.5 21 nov 2010 A versão 0.9.5 deve ser considerada a primeira versão candidata a CoffeeScript 1.0. Existiram um grande número de mudanças internas desde a última versão, muitos contribuiram do dialeto CoffeeScript Coco. Heregexes (regexes estendidas) foram adicionadas. Funções agora podem ter valores padrão em seus argumentos. Corpo das classes agora são código executável. Melhorias nos erros de sintaxe para CoffeeScript inválido. nudefined agora funciona como null, e não pode ser atribuído a um novo valor. Houveram mudanças nas regras de precedência em relação a comprehensions single-line: result = i for i in list
era analisado (parsed) em result = (i for i in list) por padrão ... agora é analisado (parsed) em
(result = i) for i in list.

0.9.4 21 set 2010 CoffeeScript agora usa melhores nomes de variáveis temporárias, e recicla suas referências depois do uso. Adicionado suporte a require.extensions para o Node.js 0.3. Carregar CoffeeScript no navegador agora adiciona apenas um objeto CoffeeScript no escopo global. Correções de bug em objetos implícitos e comentários em bloco em alguns casos extremos.

0.9.3 16 set 2010 Switch agora compila para switch nativo de JavaScript — eles antigamente compilavam para if/else encadeados para compatibilidade com a versão 1.3 do JavaScript. Absorver a invocação de uma função agora é suportado. Usuários do editor RubyMine agora podem utilizar a flag --watch.

0.9.2 23 ago 2010 Especificar o começo e fim de um range literal agora é opcional, ex. array[3..]. Agora é possível usar a not instance of. Importante correção de bug com indentação aninhada significante e não-significante (Issue #637). Adicionado a flag --require que permite que você ligue com o comando coffee. Adicionado um arquivo jsl.conf customizado para a sua instalação preferida de JavaScriptLint. Maior velocidade no tempo de compilação da gramática Jison. Comentários em bloco agora podem ser usados com uma sintaxe amigável a minifiers JavaScript. Adicionados operadores de atribuição compostos bitwise. Correção de bugs nos objetos literais implícitos com chaves iniciadas em números e string, como o sujeito de chamadas implícitas, e como parte de atribuições compostas.

0.9.1 11 ago 2010 Correções de bug para 0.9.1. Melhora a manipulação de objetos implícitos mistos, chamadas implícitas a funções, e identação implícita. Interpolação de strings e regex agora é feita apenas com #{ ... }, como em Ruby.

0.9.0 4 ago 2010 As série de versões 0.9 são candidatas para o lançamento da versão 1.0. A versão 0.9 introduz várias mudanças que quebram a compatibilidade com versões anteriores: atribuições agora usam =, e objetos literais usam :, como em JavaScript. Isto permite termos objetos literais implícitos, e definições de objetos no estilo YAML. Meia atribuições (half assignments) foram removidas, devido a +=, or=, e outros. Interpolação agora usa # ao invés de $ — pois o sinal de dólar pode fazer parte de um indentificador JS válido. Range comprehensions ao contrário são seguras novamente, e otimizadas para laços for quando criadas com números inteiros como final do laço. Um forma sem proteção e rápida de object comprehension foi adicionada: for all key, value of object. O uso da palavra-chave super sem argumentos agora redireciona todos os argumentos passados a função, como em Ruby. Se você estender (extends) a classe B da classe pai A, e se A possui um método extended definido, ele irá ser chamado, passando B — isto habilita herança estática, entre outras coisas. Saída mais limpa para bound functions com =>. @variables agora podem ser usadas nas listas de parâmetros, com o parâmetro sendo automaticamente setado como uma propriedade do objeto — útil em construtores e setter functions. Contrutores agora podem receber splats.

0.7.2 12 jul 2010 Rápida correção de bug (logo depois da 0.7.1) de um problema que impedia que algumas opções da linha de comando coffee fossem tratadas de forma correta em algumas circunstâncias.

0.7.1 11 jul 2010 Comentários no estilo bloco agora são passados e imprimidos como comentários em bloco JavaScript -- fazendo deles úteis para licenças e cabeçalhos de direitos legais (copyright). Melhor suporte na execução de scripts coffee via hashbangs. Melhoria nos erros de sintaxe para tokens que não estão na gramática.

0.7.0 28 jun 2010 O estilo oficial de variáveis no CoffeeScript agora é camelCase, assim como em JavaScript. Palavras reservadas agora podem ser chaves de objetos, e serão automaticamente postas entre aspas para você. Comprehensions de range agora geram um código mais limpo, mas você tem de especificar by -1 se deseja iterar ao contrário. Relatório de erros de sintaxe foram bastante melhorados desde a última versão. Executando coffee sem argumentos agora chama o REPL, com suporte a Readline. O operador de bind <- foi removido do CoffeeScript. A palavra-chave loop foi adicionada, o que é equivalente ao laço while true. Comprehensions que possuem closures agora vão fechar sobre suas variáveis, como na semântica de um forEach. Agora é possível usar bound functions nas definições de classes. Por consistência, a in b é agora uma checagem de presença no array, e a of b é uma checagem de chave no objeto. Comentários não são mais passados para o JavaScript gerado.

0.6.2 15 mai 2010 O comando coffee agora preserva a estrutura de pastas quando compila um diretório cheio de scripts. Corrigido duas omissões que impediam o compilador CoffeeScript de rodar dentro do Internet Explorer. Existe agora uma sintaxe para comentários em bloco, similar a sintaxe já existente para heredocs. Pattern matching ao estilo ECMA Harmony DRY (Don't Repeat Yourself) é agora suportado, onde o nome da propriedade é o mesmo nome do valor: {name, length}: func. Pattern matching agora é permitido dentro de variáveis comprehension. unless é agora suportado como um bloco. Laços until foram adicionados, como o inverso dos laços while. Declarações switch agora são permitidas sem o objeto de cláusulas. Compatível com Node.js v.0.1.95.

0.6.1 12 abr 2010 Atualização do CoffeeScript para compatibilidade com o novo Node.js v0.1.90

0.6.0 3 abr 2010 Vírgulas no fim das linhas agora são permitidas, a-la Python. Propriedades estáticas agora podem ser atribuídas dentro das definições de classes, usando a notação @propriedade.

0.5.6 23 mar 2010 Interpolação agora pode ser usada dentro de expressões regulares and heredocs, assim como em strings. Adicionado o operador <- para binding. Atribuição de meia-expressões agora são permitidas ao invés do ||=. O objeto arguments não é mais convertido automaticamente em array. Após o require, Node.js pode diretamente carregar arquivos .coffee, graças a registerExtension. Splats múltiplos agora podem ser usados nas chamadas de funções, arrays e em combinação de padrões (pattern matching).

0.5.5 8 mar 2010 Interpolação de strings, contribuído por Stan Angeloff. Uma vez que --run está ativo por padrão desde a versão 0.5.3, atualiza --stdio e --eval para também rodarem por padrão, passe a flag compile se quiser também imprimir o resultado.

0.5.4 3 mar 2010 Correção de bug que corrige as constantes globais __filename e __dirname do Node.js. Pequenas alterações para uma análise sintática mais flexível de funções aninhadas e comentários mal indentados. Atualizações para a última API do Node.js.

0.5.3 27 fev 2010 CoffeeScript agora tem uma sintaxe para definição de classes. Muitos dos componentes do core (Node, Lexer, Rewriter, Scope, Optparse) estão a usando. Cakefiles podem usar optparse.coffee para definir opções para tasks. --run agora é a flag padrão para o comando coffee, use --compile para salvar JavaScripts. Correção de bug em uma ambiguidade entre RegExp literais e divisões encadeadas.

0.5.2 25 fev 2010 Adicinonada uma versão comprimida do compilador para inclusão em páginas web como
extras/coffee-script.js. Ele irá automaticamente rodar qualquer tag de script do tipo text/coffeescript. Adiciona a opção --stdio ao comando coffee, para uso com o pipe.

0.5.1 24 fev 2010 Melhorias na absorção de referências nulas (null soaking) com o operador existencial, incluindo a absorção em propriedades indexadas. Adicionado condições aos laços while, o que permite agora usá-los como filtros com when, da mesma forma que comprehensions.

0.5.0 21 fev 2010 A versão 0.5.0 do CoffeScript é um grande lançamento (major release). Ao mesmo tempo que não existe mudanças na linguagem, o compilador Ruby foi removido em troca de um compilador escrito em CoffeeScript.

0.3.2 8 fev 2010 @propriedade agora serve como um atalho para this.propriedade.
Node.js agora é o engine padrão. Caso queira continuar a usar a antiga engine, Narwhal, passe a flag --narwhal.

0.3.0 26 jan 2010 CoffeeScript 0.3 inclui grandes mudanças na sintaxe:
O símbolo para função foi modificado para ->, e o símbolo para bound function agora é =>.
Listas de parâmetros nas definições de funções agora devem estar entre parênteses.
Adicionado property soaking, com o operador ?..
Parênteses agora são opcionais quando funções com argumentos são invocadas.
Removida a sintaxe obsoleta de bloco literal.

0.2.6 17 jan 2010 Adicionado comparações em cadeia como em Python, o operador de existência ?=, e alguns exemplos do Beautiful Code. Correções de bugs relacionados a conversão de declarações para expressões, conversão de argumentos para array, e o syntax highlighter para TextMate.

0.2.5 13 jan 2010 As condições dos switchs agora aceitam vários valores ao mesmo tempo — Se algum deles for verdadeiro, o case irá rodar. Adicionado a senta longa ==>, que define e imediatamente vincula (bind) uma função ao this. Laços while agora podem ser usados como expressões, do mesmo modo como comprehensions podem. Splats podem ser usadas dentro de padrões de combinação para capturar o resto de um array.

0.2.4 12 jan 2010 Adicionada a atribuição de desestruturação seguindo a proposta do ECMAScript Harmony, para tratar da extração de valores de arrays e objetos aninhados. Adicionado heredocs sensíveis a indentação (indentation-sensitive) para uma melhor formatação de strings ou pedaços de código.

0.2.3 Jan 11, 2010 Removida a palavra-chave ino, sendo substituída por of para object comprehensions. Agora elas funcionam da seguinte forma: for prop, value of object.

0.2.2 10 de jan 2010 Quando executar uma comprehension sobre um objeto, usar ino, ao invés de in, o que ajuda a gerar um código menor e mais eficiente durante a compilação. Adicionado :: como um atalho para .prototype. O símbolo para "splat" foi modificado de um asterisco * prefixado para reticências ... com sufixos. Adicionado o operador in de JavaScript, decalarações return vazias, laços while vazios. Funções contrutoras que iniciam com uma letra maiúscula agora incluem uma checagem de segurança para assegurar que a nova instância do objeto seja retornada. A palavra-chave extends agora funciona de forma idêntica a goog.inherits da Google Closure Library.

0.2.1 5 jan 2010 Objetos passados como argumentos agora são convertidos em arrays reais quando referenciados.

0.2.0 5 jan 2010 Grande lançamento (major release). Espaço em branco significativo. Melhor conversão de declaração para expressão. Splats. Literais splice. Comprehensions de objetos. Blocos. Operador existencial. Muito obrigado a todos que postaram issues, com um agradecimento especial para Liam O'Connor-Davis pela ajuda com espaço em branco e expressões.

0.1.6 27 dez 2009 Correção de bug para rodar coffee --interactive e --run fora do diretório CoffeeScript. Correção de bug para funções e if aninhados.

0.1.5 26 dez 2009 Literais Array slice e array comprehensions podem ambos utilizar uma sintaxe no estilo Ruby para especificar o começo e fim de um range. Declaração de variáveis JavaScript agora são enviadas para o topo do escopo, fazendo com que todas as declarações de atribuição fiquem dentro de expressões. É possível usar \ para "escapar" (escape) novas linhas. O comando coffee-script agora é chamado coffee.

0.1.4 25 dez 2009 A extensão oficial do CoffeScript agora é .coffee ao contrário de .cs, que pertence a C#. Devido a vários pedidos, agora é possível usar = para atribuição. Diferente de JavaScript, = pode também ser usado dentro de objetos literais, da mesma forma que :. Feita uma correção gramatical para chamadas de funções em cadeia (chain calls) como func(1)(2)(3)(4). Herança e a palavra-chave super não utilizam mais __proto__, fazendo com sejam compatíveis com o IE.

0.1.3 25 dez 2009 O comando coffee agora inclui a opção --interactive, que chama uma sessão inteterativa do CoffeeScript, e --run, que compila e executa um script. Ambas as opções dependem da instalação do Narwhal. A palavra-chave aint foi trocada por isnt, o que faz mais sentindo junto com is. Strings com aspas agora são permitidas como identificadores dentro de objetos literais: ex. {"5+5": 10}. Todos os operadores de atribuição agora usam dois pontos: +:, -:, *:, etc.

0.1.2 24 dez 2009 Corrigido um bug quando super() era chamado por mais de um nível de herança, com a re-adição da palavra-chave extends. Adicionado suporte experimental a Narwhal (como um pacote Tusk), contribuído por Tom Robinson, incluindo bin/cs como um REPL de CoffeeScript e interpretador. Nova opção --no-wrap para suprimir o wrapper da função de segurança.

0.1.1 24 dez 2009 Adicionado instanceof e typeof como operadores.

0.1.0 24 dez 2009 Primeira versão do CoffeeScript liberada.



Traduzido para o português por Loop Infinito (@loopinfinito).