Google News
logo
CoffeeScript Interview Questions
CoffeeScript 1 provided the class and extends keywords as syntactic sugar for working with prototypal functions. With ES2015, JavaScript has adopted those keywords; so CoffeeScript 2 compiles its class and extends keywords to ES2015 classes.
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;
​
Animal = class Animal {
  constructor(name) {
    this.name = name;
  }
​
  move(meters) {
    return alert(this.name + ` moved ${meters}m.`);
  }
​
};
​
Snake = class Snake extends Animal {
  move() {
    alert("Slithering...");
    return super.move(5);
  }
​
};
​
Horse = class Horse extends Animal {
  move() {
    alert("Galloping...");
    return super.move(45);
  }
​
};
​
sam = new Snake("Sammy the Python");
​
tom = new Horse("Tommy the Palomino");
​
sam.move();
​
tom.move();​
​
Static methods can be defined using @ before the method name:
class Teenager
  @say: (speech) ->
    words = speech.split ' '
    fillers = ['uh', 'um', 'like', 'actually', 'so', 'maybe']
    output = []
    for word, index in words
      output.push word
      output.push fillers[Math.floor(Math.random() * fillers.length)] unless index is words.length - 1
    output.join ', '
​
var Teenager;
​
Teenager = class Teenager {
  static say(speech) {
    var fillers, i, index, len, output, word, words;
    words = speech.split(' ');
    fillers = ['uh', 'um', 'like', 'actually', 'so', 'maybe'];
    output = [];
    for (index = i = 0, len = words.length; i < len; index = ++i) {
      word = words[index];
      output.push(word);
      if (index !== words.length - 1) {
        output.push(fillers[Math.floor(Math.random() * fillers.length)]);
      }
    }
    return output.join(', ');
  }
​
};​
​
Finally, class definitions are blocks of executable code, which make for interesting metaprogramming possibilities. In the context of a class definition, this is the class object itself; therefore, you can assign static properties by using @property: value.
In addition to supporting ES2015 classes, CoffeeScript provides a shortcut for working with prototypes. The :: operator gives you quick access to an object’s prototype :
String::dasherize = ->
  this.replace /_/g, "-"
​
String.prototype.dasherize = function() {
  return this.replace(/_/g, "-");
};
switch statements in JavaScript are a bit awkward. You need to remember to break at the end of every case statement to avoid accidentally falling through to the default case. CoffeeScript prevents accidental fall-through, and can convert the switch into a returnable, assignable expression. The format is: switch condition, when clauses, else the default case.
 
As in Ruby, switch statements in CoffeeScript can take multiple values for each when clause. If any of the values match, the clause runs.
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);
}​

switch statements can also be used without a control expression, turning them in to a cleaner alternative to if/else chains.
score = 76
grade = switch
  when score < 60 then 'F'
  when score < 70 then 'D'
  when score < 80 then 'C'
  when score < 90 then 'B'
  else 'A'
# grade == 'C'
​
var grade, score;
​
score = 76;
​
grade = (function() {
  switch (false) {
    case !(score < 60):
      return 'F';
    case !(score < 70):
      return 'D';
    case !(score < 80):
      return 'C';
    case !(score < 90):
      return 'B';
    default:
      return 'A';
  }
})();
​
// grade == 'C'
try expressions have the same semantics as try statements in JavaScript, though in CoffeeScript, you may omit both the catch and finally parts. The catch part may also omit the error parameter if it is not needed.
try
  allHellBreaksLoose()
  catsAndDogsLivingTogether()
catch error
  print error
finally
  cleanUp()
​
var error;
​
try {
  allHellBreaksLoose();
  catsAndDogsLivingTogether();
} catch (error1) {
  error = error1;
  print(error);
} finally {
  cleanUp();
}
​
 
Similar to block strings and comments, CoffeeScript supports block regexes extended regular expressions that ignore internal whitespace and can contain comments and interpolation. Modeled after Perl’s /x modifier, CoffeeScript’s block regexes are delimited by /// and go a long way towards making complex regular expressions readable. To quote from the CoffeeScript source:
NUMBER     = ///
  ^ 0b[01]+    |              # binary
  ^ 0o[0-7]+   |              # octal
  ^ 0x[\da-f]+ |              # hex
  ^ \d*\.?\d+ (?:e[+-]?\d+)?  # decimal
///i
​
var NUMBER;
​
NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i; // binary
// octal
// hex
// decimal
ES2015 modules are supported in CoffeeScript, with very similar import and export syntax :
import './local-file.js' # Must be the filename of the generated file
import 'package'
​
import _ from 'underscore'
import * as underscore from 'underscore'
​
import { now } from 'underscore'
import { now as currentTimestamp } from 'underscore'
import { first, last } from 'underscore'
import utilityBelt, { each } from 'underscore'
​
import dates from './calendar.json' assert { type: 'json' }
​
export default Math
export square = (x) -> x * x
export class Mathematics
  least: (x, y) -> if x < y then x else y
​
export { sqrt }
export { sqrt as squareRoot }
export { Mathematics as default, sqrt as squareRoot }
​
export * from 'underscore'
export { max, min } from 'underscore'
export { version } from './package.json' assert { type: 'json' }
import './local-file.js';
​
import 'package';
​
import _ from 'underscore';
​
import * as underscore from 'underscore';
​
import {
  now
} from 'underscore';
​
import {
  now as currentTimestamp
} from 'underscore';
​
import {
  first,
  last
} from 'underscore';
​
import utilityBelt, {
  each
} from 'underscore';
​
import dates from './calendar.json' assert {
  type: 'json'
};
​
export default Math;
​
export var square = function(x) {
  return x * x;
};
​
export var Mathematics = class Mathematics {
  least(x, y) {
    if (x < y) {
      return x;
    } else {
      return y;
    }
  }
​
};
​
export {
  sqrt
};
​
export {
  sqrt as squareRoot
};
​
export {
  Mathematics as default,
  sqrt as squareRoot
};
​
export * from 'underscore';
​
export {
  max,
  min
} from 'underscore';
​
export {
  version
} from './package.json' assert {
    type: 'json'
  };
 
Dynamic import is also supported in CoffeeScript, with mandatory parentheses:
# Your browser must support dynamic import to run this example.
​
do ->
  { run } = await import('./browser-compiler-modern/coffeescript.js')
  run '''
    if 5 < new Date().getHours() < 9
      alert 'Time to make the coffee!'
    else
      alert 'Time to get some work done.'
  '''
// Your browser must support dynamic import to run this example.
(async function() {
  var run;
  ({run} = (await import('./browser-compiler-modern/coffeescript.js')));
  return run(`if 5 < new Date().getHours() < 9
  alert 'Time to make the coffee!'
else
  alert 'Time to get some work done.'`);
})();
​
Hopefully, you’ll never need to use it, but if you ever need to intersperse snippets of JavaScript within your CoffeeScript, you can use backticks to pass it straight through.
hi = `function() {
  return [document.title, "Hello JavaScript"].join(": ");
}`
​
var hi;
​
hi = function() {
  return [document.title, "Hello JavaScript"].join(": ");
};
Escape backticks with backslashes : \`​ becomes `​.
 
Escape backslashes before backticks with more backslashes : \\\`​ becomes \`​.
markdown = `function () {
  return \`In Markdown, write code like \\\`this\\\`\`;
}`
​
var markdown;
​
markdown = function () {
  return `In Markdown, write code like \`this\``;
};​
​
You can also embed blocks of JavaScript using triple backticks. That’s easier than escaping backticks, if you need them inside your JavaScript block.
```
function time() {
  return `The time is ${new Date().toLocaleTimeString()}`;
}
```
​
function time() {
  return `The time is ${new Date().toLocaleTimeString()}`;
}
;
JSX is JavaScript containing interspersed XML elements. While conceived for React, it is not specific to any particular library or framework.
 
CoffeeScript supports interspersed XML elements, without the need for separate plugins or special settings. The XML elements will be compiled as such, outputting JSX that could be parsed like any normal JSX file, for example by Babel with the React JSX transform. CoffeeScript does not output React.createElement calls or any code specific to React or any other framework. It is up to you to attach another step in your build chain to convert this JSX to whatever function calls you wish the XML elements to compile to.
 
Just like in JSX and HTML, denote XML tags using < and >. You can interpolate CoffeeScript code inside a tag using { and }. To avoid compiler errors, when using < and > to mean “less than” or “greater than,” you should wrap the operators in spaces to distinguish them from XML tags. So i < len, not i<len. The compiler tries to be forgiving when it can be sure what you intend, but always putting spaces around the “less than” and “greater than” operators will remove ambiguity.
renderStarRating = ({ rating, maxStars }) ->
  <aside title={"Rating: #{rating} of #{maxStars} stars"}>
    {for wholeStar in [0...Math.floor(rating)]
      <Star className="wholeStar" key={wholeStar} />}
    {if rating % 1 isnt 0
      <Star className="halfStar" />}
    {for emptyStar in [Math.ceil(rating)...maxStars]
      <Star className="emptyStar" key={emptyStar} />}
  </aside>
​
var renderStarRating;
​
renderStarRating = function({rating, maxStars}) {
  var emptyStar, wholeStar;
  return <aside title={`Rating: ${rating} of ${maxStars} stars`}>
    {(function() {
    var i, ref, results;
    results = [];
    for (wholeStar = i = 0, ref = Math.floor(rating); (0 <= ref ? i < ref : i > ref); wholeStar = 0 <= ref ? ++i : --i) {
      results.push(<Star className="wholeStar" key={wholeStar} />);
    }
    return results;
  })()}
    {rating % 1 !== 0 ? <Star className="halfStar" /> : void 0}
    {(function() {
    var i, ref, ref1, results;
    results = [];
    for (emptyStar = i = ref = Math.ceil(rating), ref1 = maxStars; (ref <= ref1 ? i < ref1 : i > ref1); emptyStar = ref <= ref1 ? ++i : --i) {
      results.push(<Star className="emptyStar" key={emptyStar} />);
    }
    return results;
  })()}
  </aside>;
};
Older plugins or forks of CoffeeScript supported JSX syntax and referred to it as CSX or CJSX. They also often used a .cjsx file extension, but this is no longer necessary; regular .coffee will do.