1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00
jashkenas--coffeescript/documentation/sections/breaking_changes.md
Geoffrey Booth d20f54967e [CS2] 2.0.0-beta1 docs (#4494)
* Update package versions; remove marked

* Revise docs to use Markdown-It: tables are now GitHub-Flavored Markdown tables, avoid hack of blockquoted code blocks

* Add anchors for sub-sections

* Add syntax highlighting to uneducable code blocks; fix missing italics variant for comments font

* Update docs about breaking changes in Literate CoffeeScript, move Breaking Changes section below Literate CoffeeScript section

* Update docs regarding destructuring default values breaking change

* Update changelog, with spitball release date for beta1

* Fix highlight function return statement
2017-04-09 23:07:58 -07:00

4.9 KiB
Raw Blame History

Breaking Changes From CoffeeScript 1.x to 2

CoffeeScript 2 aims to output as much idiomatic ES2015+ syntax as possible with as few breaking changes from CoffeeScript 1.x as possible. Some breaking changes, unfortunately, were unavoidable.

Default values for function parameters and destructured elements

Per the ES2015 spec regarding function default parameters and destructuring default values, default values are only applied when a value is missing or undefined. In CoffeeScript 1.x, the default value would be applied in those cases but also if the value was null.

codeFor('breaking_change_function_parameter_default_values', 'f(null)')
codeFor('breaking_change_destructuring_default_values', 'a')

Bound generator functions

Bound generator functions, a.k.a. generator arrow functions, arent allowed in ECMAScript. You can write function* or =>, but not both. Therefore, CoffeeScript code like this:

f = => yield this
# Throws a compiler error

Needs to be rewritten the old-fashioned way:

codeFor('breaking_change_bound_generator_function')

Classes are compiled to ES2015 classes

ES2015 classes and their methods have some restrictions beyond those on regular functions.

Class constructors cant be invoked without new:

(class)()
# Throws a TypeError at runtime

Derived (extended) class constructors cannot use this before calling super:

class B extends A
  constructor: -> this
  # Throws a compiler error

Class methods cant be used with new (uncommon):

class Namespace
  @Klass = ->
new Namespace.Klass
# Throws a TypeError at runtime

Bare super

Due to a syntax clash with super with accessors, bare super no longer compiles to a super call forwarding all arguments.

class B extends A
  foo: -> super
  # Throws a compiler error

Arguments can be forwarded explicitly using splats:

codeFor('breaking_change_super_with_arguments')

Or if you know that the parent function doesnt require arguments, just call super():

codeFor('breaking_change_super_without_arguments')

super in non-class methods

In CoffeeScript 1.x it is possible to use super in more than just class methods, such as in manually prototype-assigned functions:

A = ->
B = ->
B extends A
B.prototype.foo = -> super arguments...
# Throws a compiler error

Due to the switch to ES2015 super, this is no longer supported. The above case could be refactored to:

codeFor('breaking_change_super_in_non-class_methods_refactor_with_apply')

or

codeFor('breaking_change_super_in_non-class_methods_refactor_with_class')

Dynamic class keys exclude executable class scope

Due to the hoisting required to compile to ES2015 classes, dynamic keys in class methods cant use values from the executable class body unless the methods are assigned in prototype style.

class A
  name = 'method'
  "#{name}": ->   # This method will be named 'undefined'
  @::[name] = ->  # This will work; assigns to `A.prototype.method`

Literate CoffeeScript now parsed by a Markdown library

The CoffeeScript 1.x implementation of Literate CoffeeScript relies on indentation to tell apart code blocks from documentation, and as such it can get confused by Markdown features that also use indentation like lists. In CoffeeScript 2 this has been refactored to now use Markdown-It to detect Markdown sections rather than just looking at indentation. The only significant difference is that now if you want to include a code block in documentation, as opposed to the compiler recognizing that code block as code, it must have at least one line fully unindented. Wrapping it in HTML tags is no longer sufficient.

Code blocks interspersed with lists may need to be refactored. In general, code blocks should be separated by a blank line between documentation, and should maintain a consistent indentation level—so an indentation of one tab (or whatever you consider to be a tab stop, like 2 spaces or 4 spaces) should be treated as your codes “left margin,” with all code in the file relative to that column.