JavaScript, the good parts + syntactic sugar = CoffeeScript

27

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 of JavaScript, the good parts + syntactic sugar = CoffeeScript

Page 1: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 2: JavaScript, the good parts + syntactic sugar = CoffeeScript

Good/Bad PartsSyntactic Sugar

Classes

JavaScript,

the good parts

+

syntactic sugar

=

Co�eeScript

Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript

Page 3: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 4: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 5: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 6: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 7: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 8: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 9: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 10: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 11: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 12: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 13: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 14: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 15: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 16: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 17: JavaScript, the good parts + syntactic sugar = CoffeeScript

Good/Bad PartsSyntactic Sugar

Classes

Lexical Scoping, Globalsfor ownswitchExistential Operator

[optional] comparision

0 == ""

Use === instead

Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript

Page 18: JavaScript, the good parts + syntactic sugar = CoffeeScript

Good/Bad PartsSyntactic Sugar

Classes

Lexical Scoping, Globalsfor ownswitchExistential Operator

[optional] comparision

0 == ""

Use === instead

Vladimir Dobriakov, www.mobile-web-consulting.de Co�eeScript

Page 19: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 20: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 21: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 22: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 23: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 24: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 25: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 26: JavaScript, the good parts + syntactic sugar = CoffeeScript

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

Page 27: JavaScript, the good parts + syntactic sugar = CoffeeScript

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