Jazoon 2012, Zürich

Working Effectively with JavaScript

bit.ly/drtom-jazoon2012

Thomas Schank, Ph.D.

Senior Software Engineer, ZHdK
  • Zurich University of the Arts

→ next slide / uncover

← previous

This presentation uses HTML5. It is known to work well with recent versions of Chrome or Firefox.

Table of Contents

  • Intro
  • The Language

    • Functions
    • Objects and Inheritance
    • The Event-Loop
  • Wrappers

  • Libraries

  • Other Considerations

  • Summary

madek

Ruby (on Rails)

JavaScript

(CoffeeScript)

Haml/HTML
Sass/CSS
SQL
(pg)pl/SQL

Ph.D. @ KIT

Algorithms
Graphs
Datastructures
Analytics
Complexity
Web
Architecture
DataStores
Programming
Java
JEE
C#
C++
Scala
F#
Ruby
JavaScript
Haskell
Clojure

1988

Turbo C++

2008

JavaScript - Why Care?

Reach

  • Firefox
  • IE
  • Opera
  • Chrome
  • Safari
  • Linux
  • Windows
  • Apple
  • Android
  • Nodejs
  • Riak
  • CouchDB
  • MongoDB
Language Popularity
popular languages at gihub May, 14th 2012
popular languages at gihub May, 14th 2012

 Number of Questions/Month on StackOverflow: Java (red) vs JavaScript

Breaking Monoliths

Web Services

RESTful HTTP

Browser Aggregation

monolith murten

JavaScript - Quiz

> "Foo" + 1

'Foo1'

> "Foo" - 1

NaN

> "Foo" + (-1)

'Foo-1'

> 0.1 + 0.2 == 0.3

false

> 0/0

NaN

> typeof NaN

'number'

> NaN == NaN

false

> parseInt("0")

0

> parseInt("Foo")

NaN

> parseInt("07")

7

> parseInt("08")

0

> undefined == false

false

> false == null

false

> undefined == null

true

"The lack of transitivity is alarming."

D. Crockford "JavaScript - The Good Parts"

> !![]

true

> +[][[]]

NaN

...

Why?

JavaScript - Birth

10 Days

1995

Brendan Eich

Self
Java/C
Scheme

Functional JavaScript

var f = function(){};

Scope

lexical

  • var
  • hoisting

Java: {}

JavaScript: Functions

Closures

closure

var createCounter= function() {
  var i = 0;
  return function() {
    return ++i;
  };
};
> var counter = createCounter()

> counter()
1
> counter()
2
  • mashups
  • security
  • information hiding
  • security: Crockford's example with Arrays

Objects

object = map: keys → values

traditional and dot-notation

var o = new Object()
o.key_one = "value_one"

object literal notation

var o = {'key_one': 'value_one'}

[] notation and utf-8

o[' 平和 ']='???'

methods & functions

o.mymethod = function(){}

(most) things in JS are an object

this

Class Free Objects and Inheritance

Java: classes ≠ objects

Ruby: classes are objects

JavaScript: class free

Prototypal Inheritance with Object.create

v8, spidermonkey: car.__proto__

var car = {};
car.honk= function(){
  return "tröööööööt"};

var my_blue_car = Object.create(car);
my_blue_car.color = "blue";
my_blue_car.honk();

Object.create

since ES5

  • no point in distinguising class- and instance-methods
  • everything is "open", since objects are just hashes
  • catch: ES5 only

The Illusion of Classes - Constructor Functions

var my_car = new Car();
new

Constructor Function

> var Car = function(){};
> Car.prototype = Object.prototype;

prototype property

instanceof

> my_car instanceof Car;
true
> my_car instanceof Object;
true

idiomatic ???

  • it is possible to set-up
  • it's an illusion
  • Car is just a function
  • the function "hides" the prototype of your instance
  • it is still there and it is open
  • Car is an initializer function
  • it uses this to set-up properties of the new instance
  • the new keyword set-up this corretly, if you accidentially for get it ...

The Event-Loop

sleep

"And here is how I implemented sleep in JavaScript:"
var sleep = function(duration) {
  var start = (new Date()).getTime();
  while ((new Date()).getTime() < start + duration){};
};

sleep(10000);
alert("10 seconds have passed")

Events And Callbacks

Events / Callbacks

var alertPassed = function(){
  alert("10 seconds have passed");
}
setTimeout (alertPassed , 10000);

Why not?:

setTimeout(alert("10 seconds have passed"), 10000);

Lambda:

setTimeout((function() {
  alert("10 seconds have passed");
  }), 1000);

Continuation Passing Style

The Pyramid of Doom

start = (cont) ->                                                                                                                                                                            
  filetracker =  helpers.asynchelper.createTaskTracker ((err) -> cont(err))
  outerDone = filetracker.createTask("outer") 
  push_dir = (dir) ->
    fulldir = sourcedir+"/"+dir     
    readdir_done = filetracker.createTask(dir)
    fs.readdir fulldir, (err,files) ->
      else files.forEach (filename) ->
        unless filename.match /^_/ # files beginning with underscore are reserved for internal couchdev and couchdb usage
          fullpath = fulldir+"/"+filename 
          filedone = filetracker.createTask fullpath 
          fs.stat fullpath, (err,stat)->  
            if err? then filedone(err)      
            else
              if stat.isDirectory()           
                docname = dir + "/" + (fullpath.match /\/([^\/]*)$/)[1]
                readDocument fullpath , (err,doc)->
                  if err? then filedone({"readDocument":"failed for "+fullpath,"err":err})
                  else putDoc docname,doc, (err)->
                    if not err?                     
                      if (docname.match /^[\/]*_design/) then  count_pushed_design_docs += 1
                      else count_pushed_data_docs += 1
                    filedone(err)                   
              else filedone()
      readdir_done()
  push_dir "" if push_datadocs    
  push_dir "/_design" if push_designdocs
  outerDone()

Syntactic Sugar

Continuation Monad, ICS, Fibers, ...

Sugar coating?

Or just Sugar-Coating?

Rails: RJS

"Experience has shown us that if you want JavaScript code in your application, learn JavaScript and write it!"
Fernandez: The Rails 3 Way

Java: GWT

"GWT is a reasonable implementation of a poor architectural choice."
ThoughtWorks, 2011
The golden rule of CoffeeScript is: "It's just JavaScript".

Libraries

General Purpose DOM Libraries

Prototype.js

DOJO

JQuery

JQuery
Frameworks and MV* Libraries
Backbone
Spine
Cappuccino
ExtJS
JavaScriptMVC
Knockout
qooxdoo
Sproutcore
Ember

Other Considerations

Performance
  • JavaScript is fast; on par with F#, Scala
  • you can make ist very slow
  • ain't broken: don't fix it
  • understand algorithms, datastructures, and complexity
  • know your datasize, experience matters
  • consider target platforms
  • stronger type systems
  • no with statement
  • 'this' is always well defined
  • removes with statement
  • again: looks like c/java
  • good implementation; why such an ugly syntax

Namespaces

com.whatever.lib.foo.bar.mess.and.more.and.more.stuff
dependency new-hip-thing
    requires com.whoknows.lib, version >= 2.7.1-SNAPSHOT

dependency freaking-old-stuff 
    requires com.whoknows.lib, version ==  0.0.9

What Now?

JS

technial issue

Namespaces: Objects (+ Closures)

Dependency and module management: CommonJS, AMD, NPM

  • not an technical issue
  • namespaces have problems
  • version dependency
  • osgi

Let the Source be with You

GitLogo
GitHub
  • git: defacto standard
  • learn git and github
Conclusion Engineers

Writing non trivial JavaScript is serious business.

JavaScript is not language X.

Functional programming techniques are essential.

Conclusion Management

Your JavaScript project deserves the best engineers; not the worst.

"Very good engineers cost 20% more but are 2000% more productive."

Thank you!