Coffeescript constructor options with defaults

Coffeescript has a nice way of destructuring assignment in a class constructor, e.g.

class Person
  constructor: (options) ->
    {@name, @age, @height} = options

This is elegant and efficient and has the additional benefit of explicitly communicating anticipated class attributes, cf:

class Person
  constructor: (options={}) ->
    for key, val of options
      @[key] = val

which allows any old thing to be added to your object (although admittedly this is sometimes desirable).

Coffeescript also has a neat way of setting default values for functions, e.g.

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

But this pattern doesnt seem to transfer to destructuring class assignment.  I can’t for instance use any of these approaches:

class Person
  constructor: (options) ->
    {@name = "Ken", @age, @height} = options # (yields an "UNEXPECTED=" error) or
    {@name: "Ken", @age, @height} = options # (yields a "Ken" CANNOT BE ASSIGNED error)
    {@name ?= "Ken", @age, @height} = options # (yields an "UNEXPECTED COMPOUND ASSIGN" error)
    {@name? "Ken", @age, @height} = options # (yields an "UNEXPECTED LOGIC" error)
    {@name || "Ken", @age, @height} = options # (yields an "UNEXPECTED LOGIC" error)

It turns out that the best way (IMO) is:

class Person
  constructor: (options={}) ->
    {@age, @height} = options;
    @name = options.name ? "Ken"

Note that the default value for options is included, so as not to force a parameter on the constructor.  As always, stack overflow provides a deeper picture.

Leave a comment