[
  {
    "path": "README.md",
    "content": "# CoffeeScript equivalents in ECMAScript6/ES2015\n> Inspiration from [es6-equivalents-in-es5](https://github.com/addyosmani/es6-equivalents-in-es5)\n\n*Note: a few of these examples are taken from CoffeeScript's own website.*\n\n## Topics\n\n- [Statements as Expressions](#statements-as-expressions)\n- [Arrow Functions](#arrow-functions)\n- [Splats](#splats)\n- [Array Comprehensions](#array-comprehensions)\n- [Default Params](#default-params)\n- [String interpolation / Template strings](#string-interpolation--template-strings)\n- [Lexical Scope and Variable safety.](#lexical-scope-and-variable-safety)\n- [Function binding](#function-binding)\n- [Classes, Inheritance, and Super](#classes-inheritance-and-super)\n- [Destructuring Assignment](#destructuring-assignment)\n- [Array Slicing](#array-slicing)\n- [Array Splicing](#array-splicing)\n- [Ranges](#ranges)\n- [Chained Comprehensions](#chained-comparisons)\n- [Block Regular Expressions](#block-regular-expressions)\n- [Operators and Aliases](#operators-and-aliases)\n- [Generators](#generators)\n- [Loops and Iteration](#loops-and-iteration)\n- [Switch Statements](#switch-statements)\n\n## Statements as Expressions\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#expressions)\n\n```coffee\ngrade = (student) ->\n  unless student?\n    throw new Error 'student is required'\n  else if student.excellentWork\n    'A+'\n  else if student.okayStuff\n    if student.triedHard then 'B' else 'B-'\n  else\n    'C'\n\neldest = if 24 > 21 then 'Liz' else 'Ike'\n```\n\nES6 equivalent:\n\n```js\n// There is no exact equivalent, but there are ternary expressions for common\n// cases like above.\nconst grade = (student = new Error('student is required')) => {\n   if (student.excellentWork) {\n    return 'A+';\n  } else if (student.okayStuff) {\n    return student.triedHard ? 'B' : 'B-';\n  } else {\n    return 'C';\n  }\n}\n\nlet eldest = 24 > 21 ? 'Liz' : 'Ike';\n```\n\n*Note: you might want to watch [discussion on do-expressions](https://www.google.com/search?q=es7+\"do+expressions\") if you are interested in this feature. Note that the code below may not reflect the proposal in its current state.*\n\n```js\n// With current do-expression proposal, stage 0\nlet grade = student => do {\n  if (student == null) {\n    throw new Error('student is required')\n  } else if (student.excellentWork) {\n    'A+';\n  } else if (student.okayStuff) {\n    student.triedHard ? 'B' : 'B-';\n  } else {\n    'C';\n  }\n}\n```\n\n## Arrow Functions\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#literals)\n\n```coffee\nreadConfig = (file, parse) ->\n  new Promise (resolve) ->\n      fs.readFile file, 'utf8', (err, data) =>\n        if err?\n          reject err\n        else\n          resolve parse data\n```\n\nES6 equivalent: [![es6-doc](./js.png)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)\n\n```js\nfunction readConfig(file, parse) {\n  return new Promise(resolve =>\n    fs.readFile(file, 'utf8', (err, data) =>\n      err != null ?\n        reject(err) :\n        resolve(parse(data)));\n}\n```\n\n## Splats\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#splats)\n\n```coffee\nrace = (winner, runners...) ->\n    console.log winner, runners\n\nrace 'Bob', runnerList...\n```\n\nES6 equivalent: [![es6-doc](./js.png)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters)\n\n```js\nlet race = (winner, ...runners) =>\n    console.log(winner, runners);\n\nrace('Bob', ...runners);\n```\n\n## Array Comprehensions\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#loops)\n\n```coffee\nnumbers = [ 1, 4, 9 ];\n(Math.sqrt num for num in numbers)\n# -> [1, 2, 3]\n```\n\nES6 equivalent:\n\n```js\nlet numbers = [ 1, 4, 9 ];\nnumbers.map(num => Math.sqrt(num));\n// -> [1, 2, 3]\n```\n\nES7 equivalent: [![es6-doc](./js.png)](http://babeljs.io/docs/learn-es2015/#comprehensions)\n\n```js\nlet numbers = [ 1, 4, 9 ];\n[for (num of numbers) Math.sqrt(num)];\n// -> [1, 2, 3]\n```\n\n## Default Params\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#literals)\n\n```coffee\nlog = (message, level='log') -> console[level](message)\n```\n\nES6 equivalent: [![es6-doc](./js.png)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\n\n```js\nlet log = (message, level = 'log') => console[level](message);\n```\n\n## String interpolation / Template strings\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#strings)\n\n```coffee\ncontainer = 'mug'\nliquid = 'hot chocolate'\nconsole.log \"Filling the #{container} with #{liquid}...\"\n# -> \"Filling the mug with hot chocolate...\"\n```\n\nES6 equivalent: [![es6-doc](./js.png)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings)\n\n```js\nlet container = 'mug'\n   ,liquid = 'hot chocolate';\nconsole.log(`Filling the ${container} with ${liquid}...`);\n// -> \"Filling the mug with hot chocolate...\"\n```\n\n## Lexical Scope and Variable safety.\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#lexical-scope)\n\n```coffee\ninner = 10\nvalue = 20\n\n# literally an IIFE\ndo (inner = 5, value = 10) ->\n  console.log inner # 5\n\nconsole.log inner # 10\n```\n\nES6 equivalent: [![es6-doc](./js.png)](http://babeljs.io/docs/learn-es2015/#let-const) ([`let`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let), [`const`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const))\n\n```js\nlet inner = 10;\nconst value = 20;\n\n// A simple block\n{\n  let inner = 5;\n  \n  // not an error, despite being a constant in the outer scope\n  const value = 10;\n  console.log(inner); // 5\n}\n\nconsole.log(inner); // 10\n```\n\n## Function binding\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#fat-arrow)\n\n```coffee\nhero =\n  name: \"Batman\"\n  alterEgo: \"Bruce Wayne\"\n  enemies: ['Two-Face', 'Bane']\n  printEnemies: ->\n    @enemies.forEach((enemy) =>\n      console.log @name + \" fights \" + enemy);\n\nhero.printEnemies()\n# -> \"Batman fights Two-Face\"\n# -> \"Batman fights Bane\"\n```\n\nES6 equivalent: [![es6-doc](./js.png)](http://tc39wiki.calculist.org/es6/arrow-functions/)\n\n```js\nlet hero = {\n  name: \"Batman\",\n  alterEgo: \"Bruce Wayne\",\n  enemies: ['Two-Face', 'Bane'],\n  printEnemies() {\n    this.enemies.forEach(enemy =>\n      console.log(this.name + \" fights \" + enemy));\n  }\n};\n\nhero.printEnemies();\n// -> \"Batman fights Two-Face\"\n// -> \"Batman fights Bane\"\n```\n\n## Classes, Inheritance, and Super\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#classes)\n\n```coffee\nclass Person\n  constructor: (@name) ->\n    @movement = \"walks\"\n\n  move: (meters) ->\n    console.log \"#{@name} #{@movement} #{meters}m.\"\n\nclass Hero extends Person\n  constructor: (@name, @movement) ->\n\n  move: ->\n    super 500\n\nclark = new Person \"Clark Kent\"\nsuperman = new Hero \"Superman\", \"flies\"\n\nclark.move(100)\n# -> Clark Kent walks 100m.\nsuperman.move()\n# -> Superman flies 500m.\n```\n\nES6 equivalent: [![es6-doc](./js.png)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/class)\n\n```js\nclass Person {\n  constructor(name) {\n    this.name = name;\n    this.movement = \"walks\";\n  }\n\n  move(meters) {\n    console.log(`${this.name} ${this.movement} ${meters}m.`);\n  }\n}\n\nclass Hero extends Person {\n  constructor(name, movement) {\n    this.name = name;\n    this.movement = movement;\n  }\n\n  move() {\n    super.move(500);\n  }\n}\n\nlet clark = new Person(\"Clark Kent\");\nlet superman = new Hero(\"Superman\", \"flies\");\n\nclark.move(100);\n// -> Clark Kent walks 100m.\nsuperman.move();\n// -> Superman flies 500m.\n```\n\n## Destructuring Assignment\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#destructuring)\n\n```coffee\nhero =\n  name: \"Spider-Man\"\n  alterEgo: \"Peter Benjamin Parker\"\n  enemies: [\"Electro\", \"Doctor Octopus\"]\n\n{name, alterEgo} = hero\n# name = \"Spider-Man\"\n# alterEgo = \"Peter Benjamin Parker\"\n\n[head, tail...] = [1, 2, 3, 4, 5]\n# head = 1\n# tail = [2, 3, 4, 5]\n```\n\nES6 equivalent: [![es6-doc](./js.png)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)\n\n```js\nlet hero = {\n  name: \"Spider-Man\",\n  alterEgo: \"Peter Benjamin Parker\",\n  enemies: [\"Electro\", \"Doctor Octopus\"]\n};\n\nlet {name, alterEgo} = hero;\n// name = \"Spider-Man\"\n// alterEgo = \"Peter Benjamin Parker\"\n\nlet [head, ...tail] = [1, 2, 3, 4, 5];\n// head = 1\n// tail = [2, 3, 4, 5]\n```\n\n## Array Slicing\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#slices)\n\n```coffee\npart1 = list[0..3]  # with end\npart2 = list[0...3] # without end\npart3 = list[..3]   # start defaults to 0\npart4 = list[3..]   # end defaults to length\n\nclone = list[..] # Clone the array\n```\n\n```js\nlet part1 = list.slice(0, 3);\nlet part2 = list.slice(0, 4);\nlet part3 = list.slice(0, 3);\nlet part4 = list.slice(3);\n\n// More than one way to clone an array\nlet clone;\nclone = list.slice();\nclone = list.concat();\n```\n\n## Array Splicing\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#slices)\n\n```coffee\nnumbers[3..6] = [-3, -4, -5, -6]\nnumbers[3..6] = list\n```\n\nES6 equivalent:\n\n```js\nnumbers.splice(3, 4, -3, -4, -5, -6)\n[].splice.apply(numbers, [3, 4].concat(list))\n```\n\n## Ranges\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#loops)\n\n```coffee\nnumbers = [0...5]\npositives = [1...10]\n```\n\nES6 equivalent:\n\n```js\nlet numbers = Array(5).map((_, i) => i);\nlet positives = Array(10).slice(1).map((_, i) => i);\n\n// Or, you can make a custom range function (which is faster)\nfunction range(start, end) {\n  if (end == null) [start, end] = [0, start];\n  const ret = [];\n  while (start < end) ret.push(start++);\n  return ret;\n}\n```\n\n## Chained Comparisons\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#comparisons)\n\n```coffee\ncholesterol = 127\n\nhealthy = 60 < cholesterol < 200\n```\n\nES6 equivalent:\n\n```js\nlet cholestrol = 127;\n\nlet healthy = 60 < cholestrol && cholestrol < 200;\n```\n\n## Block Regular Expressions\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#regexes)\n\n```coffee\nOPERATOR = /// ^ (\n  ?: [-=]>             # function\n   | [-+*/%<>&|^!?=]=  # compound assign / compare\n   | >>>=?             # zero-fill right shift\n   | ([-+:])\\1         # doubles\n   | ([&|<>])\\2=?      # logic / shift\n   | \\?\\.              # soak access\n   | \\.{2,3}           # range or splat\n) ///\n```\n\nES6 equivalent:\n\n```js\n// There isn't really any. This doesn't get the engine-related caching that\n// regex literals often get.\nlet OPERATOR = new RegExp('^(' +\n  '?:[-=]>' +             // function\n   '|[-+*/%<>&|^!?=]=' +  // compound assign / compare\n   '|>>>=?' +             // zero-fill right shift\n   '|([-+:])\\\\1' +        // doubles\n   '|([&|<>])\\\\2=?' +     // logic / shift\n   '|\\\\?\\\\.' +            // soak access\n   '|\\\\.{2,3}' +          // range or splat\n')')\n```\n\n## Operators and Aliases\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#operators)\n\n- True: `true`, `yes`, `on`\n- False: `false`, `no`, `off`\n- And: `a && b`, `a and b`\n- Or: `a || b`, `a or b`\n- Not: `!a`, `not a`\n- Equality: `a == b`, `a is b`\n- Inequality: `a != b`, `a isnt b`\n- Current Instance: `@`, `this`\n- Instance Property: `@prop`, `this.prop`\n- Contains Property: `prop of object`\n- Contains Entry: `a in b`\n- Exponentiation: `x ** y`\n- Floor Division: `x // y`\n- Always-positive Modulo: `x %% y`\n\nES6 Equivalents: [![es6-doc](./js.png)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators)\n\n- True: `true`\n- False: `false`\n- And: `a && b`\n- Or: `a || b`\n- Not: `!a`\n- Equality: `a === b`\n- Inequality: `a !== b`\n- Current Instance: `this`\n- Instance Property: `this.prop`\n- Contains Property: `prop in object`\n- Contains Entry: `a.indexOf(b) >= 0`\n  - For strings (and arrays in ES7) only: `a.includes(b)`\n  - For iterables in ES6 (such as some DOM nodes): `Array.from(a).indexOf(b) >= 0`\n- Exponentiation: `Math.exp(x, y)`\n  - ES7: `x ** y`\n- Always-positive Modulo: `(a % b + b) % b`\n\n## Generators\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#fat-arrow)\n\n```coffee\nidentity = (iter) ->\n  yield from iter\n\nrange = lazyRange 10\nrange = identity range\n```\n\nES6 equivalent: [![es6-doc](./js.png)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*)\n\n```js\nfunction *lazyRange(n) {\n  for (let i = 0; i < n; i++) {\n    yield i;\n  }\n}\n\nfunction* identity(iter) {\n  yield* iter\n}\n\nlet range = lazyRange(10);\nrange = identity(range);\n```\n\n## Loops and Iteration\n\nCoffeeScript: [![cs-doc](./cs.png)](http://coffeescript.org/#loops)\n\n```coffee\nisOkay = (entry) ->\n  # ...\n\n# numbers 0-9\nconsole.log i for i in [0..10]\n\n# evens 0-8\nconsole.log i for i in [0..10] by 2\n\nnode = getFirst()\nnode = node.next while isOkay node\n\nconsole.log i for i in list\n\nconsole.log i for i in list when isOkay i\n\n# own object properties\nfor own prop, value of object\n  console.log prop\n  console.log object[prop]\n```\n\nES6 equivalent: [![es6-doc](./js.png)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)\n\n```js\nfunction isOkay(entry) {\n  // ...\n}\n\n// Standard `for` loops\nfor (let i = 0; i < 10; i++) {\n  console.log(i);\n}\n\nfor (let i = 0; i < 10; i += 2) {\n  console.log(i);\n}\n\nlet node = getFirst();\nwhile (isOkay(node)) {\n  node = node.next;\n}\n\n// `for ... of` loops\nfor (let i of list) {\n  console.log(i);\n}\n\nfor (let i of list) {\n  if (isOkay(i)) {\n    console.log(i);\n  }\n}\n\nfor (let prop of Object.keys(object)) {\n  console.log(prop);\n  console.log(object[prop]);\n}\n\n// Array methods (last three)\nArray.from(list).forEach(i => console.log(i))\n\nArray.from(list).filter(isOkay).forEach(i => console.log(i));\n\nObject.keys(object).forEach(prop => {\n  console.log(prop);\n  console.log(object[prop]);\n});\n```\n\n## Switch Statements\n\n```coffee\nswitch day\n  when \"Mon\" then go work\n  when \"Tue\" then go relax\n  when \"Thu\" then go iceFishing\n  when \"Fri\", \"Sat\"\n    if day is bingoDay\n      go bingo\n      go dancing\n  when \"Sun\" then go church\n  else go work\n```\n\nES6 Equivalent: [![es6-doc](./js.png)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch)\n\n```js\nswitch (day) {\ncase \"Mon\": go(\"work\"); break;\ncase \"Mon\": go(\"work\"); break;\ncase \"Tue\": go(\"relax\"); break;\ncase \"Thu\": go(\"iceFishing\"); break;\ncase \"Fri\": case \"Sat\":\n  if (day === \"bingoDay\") {\n    go(\"bingo\");\n    go(\"dancing\");\n  }\n  break;\ncase \"Sun\": go(\"church\"); break;\ndefault: go(\"work\");\n}\n```\n\n## Contributors\n\n- [hemanth](http://www.h3manth.com) (creator)\n- [stoeffel](https://github.com/stoeffel)\n- [impinball](https://github.com/impinball)\n"
  }
]