CoffeeScript¶
CoffeeScript is an easier syntax for JavaScript. It has a syntax inspired from Python and Ruby. The code will be transformed into real JavaScript before executing. This can be done on the fly or as a compiler before packaging and executing it in the productive environment.
Why To Use It¶
I used CoffeeScript as development language because it was very easy to write and read in contrast to ES5. It made development and maintenance easier and faster, specially in the callback sequences of JavaScript.
But with ES8 JavaScript has gained so much power, that it is no longer really necessary and development of this transpiler language got stuck.
This page lists some tricks and tips which are mostly not mentioned in the official docs.
Strings¶
Check for substring¶
if ~message.indexOf 'test'
The above syntax uses the tilde as bitwise or operator to get a boolean readable value. If the substring is found it will be true (any number), and false (0) if it isn’t. or use the following to get a real boolean type:
x = Boolean ~message.indexOf 'test'
Or use the negation:
if !~message.indexOf 'test'
Existence Operator¶
A very handy operator is the existence operator '?' which can be used to prevent errors with accessing methods of undefined:
x = table?.row?['col1']?[0] ? '-'
In the above example it is used multiple times to check for existence in each level. So if any of the table, row, 'col1', element [0] didn't exist the first part will be set to undefined. The standalone existence operator after that will set a x to a default value if the first part is not defined or null.
Arrays¶
A very handy thing with arrays is the command concatenation used like:
console.log text.split /\n/
.filter (l) -> l[0] isnt '#'
.map (l) ->
l.split /\s*,\s*/
.filter (e) -> e?
.map (e) -> e.replace '\t', '\\t'
.join '\t'
.join '\n'
In the above example a multiline text is
- split in lines
- filtered, so that lines starting with '#' are excluded
- then the line is splitted on ',' with surrounding whitespace
- empty columns will be removed
- the tabs within columns will be masked
- then the columns will be joined with tab separator
- and the lines will be joined together again
This example shows how a complete data structure is parsed, optimized and put together in an optimized form.
Objects¶
Check for empty object¶
unless obj? and Object.keys(obj).length
This will run the following code only if the object under test is not defined or is an empty object.
Control flow¶
Try without catch¶
try
funcWhichMayThrowError()
If you omit the catch the error will be suppressed.
try {
funcWhichMayThrowError();
} catch (_error) {}
Loops¶
Loop over array:
for element in arr
Counting loop:
for i in [0..n] by 1
Reverse loop:
for i in arr by -1
Loop over object:
for key of object
...
for key, value of object
...
Callbacks¶
To prevent checking for a given callback method on every call you may give it an empty default function on parameter definition:
test = (src, cb = -> ) ->
console.log 'do something'
cb()
Classes¶
Classes are made really easy using CoffeeScript:
# define a class
class Test
# make a constructor method
constructor: ->
# create instance
t = new Test
Use the @ sign in parameters to store the value in the same instance property:
class Test
# store given name in this.name
constructor: (@name) ->
# add another prototype to class
Test::done = true
Inheritance is also made easy:
class Test
constructor: (@name) ->
# extend the class
class Test2 extends Test
constructor: ->
# call the parent constructor
super 'numberTwo'
Local variables are created using = but properties are defined using ::
class Test
# local class variable/function
foo = 1
# instance variable/function
bar: 2
# or from the constructor
constructor: ->
@baz = 3
You may also use class properties/functions
class Test
# static class variable/function
@foo: 1
@bar: (name) ->
constructor: ->
# access statics
Test.bar()
# or
@constructor.bar()
# access from outside
Test.foo
Test.bar 'baz'
test = new Test
test.constructor.foo