javascript, the good parts + syntactic sugar = coffeescript
DESCRIPTION
JavaScript is an increadibly powerful and widely adopted language. It powers the web site, you are looking at, and probably the entertainment system in your next car. It allows for functional programming and offers prototype based inheritance. Unfortunately, it’s most language constructs are awkward (phony arrays, new, 0 == ”), frequently misunderstood (this, prototype, ==, for) and lead to an error prone and unmaintanable code (lexical scope, globals). Best solution is to learn the JavaScript language in more depth (I recommend “JavaScript: The Good Parts” by Douglas Crockford) and to use code style checker JSLint. In addition you can create more readable, reliable applications with CoffeeScript, a little language that keeps the original concepts, compiles into JavaScript and facilitates JavaScript best practices. Lets see, what CoffeeScript can do for you… (as presented at FrankfurtJS, October 2014)TRANSCRIPT
Good/Bad PartsSyntactic Sugar
Classes
Co�eeScript
Vladimir Dobriakov, www.mobile-web-consulting.de
FrankfurtJS, 30th of October 2014
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
JavaScript,
the good parts
+
syntactic sugar
=
Co�eeScript
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
Lexical Scoping, Globals
(function() {
var items;
items = $("li");
$("#totals").text(items.length + " items found");
}).call(this);
Co�eeScript:
items = $("li")
$("totals").text(items.length + " items found")
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
Lexical Scoping, Globals
(function() {
var items;
items = $("li");
$("#totals").text(items.length + " items found");
}).call(this);
Co�eeScript:
items = $("li")
$("totals").text(items.length + " items found")
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
Lexical Scoping, Globals
(function() {
var items;
items = $("li");
$("#totals").text(items.length + " items found");
}).call(this);
Co�eeScript:
items = $("li")
$("totals").text(items.length + " items found")
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
Lexical Scoping, Globals
(function() {
var items;
items = $("li");
$("#totals").text(items.length + " items found");
}).call(this);
Co�eeScript:
items = $("li")
$("totals").text(items.length + " items found")
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
Iterate through Properties
var propertyName, value,
__hasProp = {}.hasOwnProperty;
for (propertyName in customer) {
if (!__hasProp.call(customer, propertyName)) continue;
value = customer[propertyName];
alert(propertName, value);
}
for own propertyName, value of customer # CoffeeScript
alert(propertName, value)
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
Iterate through Properties
var propertyName, value,
__hasProp = {}.hasOwnProperty;
for (propertyName in customer) {
if (!__hasProp.call(customer, propertyName)) continue;
value = customer[propertyName];
alert(propertName, value);
}
for own propertyName, value of customer # CoffeeScript
alert(propertName, value)
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
Iterate through Properties
var propertyName, value,
__hasProp = {}.hasOwnProperty;
for (propertyName in customer) {
if (!__hasProp.call(customer, propertyName)) continue;
value = customer[propertyName];
alert(propertName, value);
}
for own propertyName, value of customer # CoffeeScript
alert(propertName, value)
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
switch
switch (day) { // JavaScript
case "Mon":
go(work);
break;
case "Tue":
go(iceFishing);
break;
default:
chill(24);
}
switch day # CoffeeScript
when "Mon" then go work
when "Tue" then go iceFishing
else chill 24
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
switch
switch (day) { // JavaScript
case "Mon":
go(work); break;
case "Tue":
go(iceFishing); break;
default:
chill(24);
}
switch day # CoffeeScript
when "Mon" then go work
when "Tue" then go iceFishing
else chill 24
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
switch
switch (day) { // JavaScript
case "Mon":
go(work); break;
case "Tue":
go(iceFishing); break;
default:
chill(24);
}
switch day # CoffeeScript
when "Mon" then go work
when "Tue" then go iceFishing
else chill 24
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
Check for Optional Parameter
if (defaultAmount)
if (defaultAmount != null)
if (typeof defaultAmount !== 'undefined' &&
defaultAmount != null)
Co�eeScript:
if defaultAmount?
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
Check for Optional Parameter
if (defaultAmount)
if (defaultAmount != null)
if (typeof defaultAmount !== 'undefined' &&
defaultAmount != null)
Co�eeScript:
if defaultAmount?
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
Check for Optional Parameter
if (defaultAmount)
if (defaultAmount != null)
if (typeof defaultAmount !== 'undefined' &&
defaultAmount != null)
Co�eeScript:
if defaultAmount?
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
Check for Optional Parameter
if (defaultAmount)
if (defaultAmount != null)
if (typeof defaultAmount !== 'undefined' &&
defaultAmount != null)
Co�eeScript:
if defaultAmount?
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
[optional] comparision
0 == ""
Use === instead
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
Lexical Scoping, Globalsfor ownswitchExistential Operator
[optional] comparision
0 == ""
Use === instead
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
List ComprehensionsSplats, Destructuring AssignmentString Interpolation
List Comprehensions
shortNames = (name for name in list when name.length < 5)
cubes = (math.cube num for num in list)
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
List ComprehensionsSplats, Destructuring AssignmentString Interpolation
Splats, Destructuring Assignment
awardMedals = (first, second, others...) ->
# TODO implementation
awardMedals 'CoffeeScript', 'JavaScript', 'Ruby', 'Python'
[city, temp, forecast] = weatherReport "Frankfurt"
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
List ComprehensionsSplats, Destructuring AssignmentString Interpolation
in/of
winner = yes if pick in
[47, 92, 13]
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
List ComprehensionsSplats, Destructuring AssignmentString Interpolation
String Interpolation
"Hello, #{name}"
html = """
<strong>
Cup of CoffeeScript
</strong>
"""
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
De�ne ClassesInitializerFat ArrowAccess Prototype
De�ne Classes
class Animal
constructor: (name) ->
@name = name
move: (meters) ->
alert "#{@name} moved #{meters}m."
class Snake extends Animal
move: ->
alert "Slithering..."
super 5
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
De�ne ClassesInitializerFat ArrowAccess Prototype
Initializer
class Animal
constructor: (@name) ->
(function() {
var Animal;
Animal = (function() {
function Animal(name) {
this.name = name;
}
return Animal;
})();
).call(this);
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
De�ne ClassesInitializerFat ArrowAccess Prototype
Fat Arrow replaces this+that
Account = (@customer, @cart) ->
$('.shopping_cart').bind 'click',
(event) =>
@customer.purchase @cart
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
De�ne ClassesInitializerFat ArrowAccess Prototype
Access Prototype
String::dasherize = ->
this.replace /_/g, "-"
String.prototype.dasherize = function() {
return this.replace(/_/g, "-");
};
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript
Good/Bad PartsSyntactic Sugar
Classes
De�ne ClassesInitializerFat ArrowAccess Prototype
References
Douglas Crockford "JavaScript: The Good Parts"
http://co�eescript.org/
Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript