Jens Ahrengot Boddum

WordPress konsulent

Det kommer til at handle om ...

Begrænsninger i JavaScript
Hvad er CoffeeScript
Er CS relevant, når ES6 er lige om hjørnet?



HTML5 & JavaScript

LocalStorage
Web Sockets
Offline Web Apps
Drag 'n Drop
SessionStorage
Geolocation
File API
Web Audio API
Web RTC
Peer-to-Peer
Canvas
WebGL

JavaScripts forbandelse

Cross-browser support af EcmaScript 6


Objekt-orienteret JavaScript

Den "lette"

 var Animal = {
  speed: 10,
  init: function(el) {
    this.x = 0;
    el.onclick = this.move;
  },
  move: function() {
    this.x += this.speed;
    console.log("Walking...");
  }
}

// Instantiate
var animal = Object.create(Animal);
animal.init( document.querySelector('.elephant') );

Whoops ... Dynamisk context

 // Helper to force a specific context in callbacks
var __bind = function(fn, me){ 
  return function(){ 
    return fn.apply(me, arguments); 
  }; 
};

var Animal = {
  speed: 10,
  init: function(el) {
    this.move = __bind(this.move, this);

    this.x = 0;
    el.onclick = this.move;
  },
  move: function() {
    this.x += this.speed;
    console.log("Walking...");
  }
}

// Instantiate
var animal = Object.create(Animal);
animal.init( document.querySelector('.elephant') );

En bedre måde

var Animal = function(el) {
  this.move = __bind(this.move, this);

  this.x = 0;
  el.onclick = this.move;
}

Animal.prototype.speed = 10;

Animal.prototype.move = function() {
  this.x += this.speed;
  console.log("Walking...");
}

// Instantiate
var animal = new Animal( document.querySelector('.elephant') );

Den "korrekte" måde


function Class() {
  var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
 
  // The base Class implementation (does nothing)
  this.Class = function(){};
 
  // Create a new Class that inherits from this class
  Class.extend = function(prop) {
    var _super = this.prototype;
   
    // Instantiate a base class (but only create the instance,
    // don't run the init constructor)
    initializing = true;
    var prototype = new this();
    initializing = false;
   
    // Copy the properties over onto the new prototype
    for (var name in prop) {
      // Check if we're overwriting an existing function
      prototype[name] = typeof prop[name] == "function" &&
        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;
           
            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = _super[name];
           
            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            var ret = fn.apply(this, arguments);        
            this._super = tmp;
           
            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }
   
    // The dummy class constructor
    function Class() {
      // All construction is actually done in the init method
      if ( !initializing && this.init )
        this.init.apply(this, arguments);
    }
   
    // Populate our constructed prototype object
    Class.prototype = prototype;
   
    // Enforce the constructor to be what we expect
    Class.prototype.constructor = Class;
 
    // And make this class extendable
    Class.extend = arguments.callee;
   
    return Class;
  };
}

// Animal class
var Animal = Class.extend({
  speed: 10,
  init: function(el){
    this.x = 0;
    
    this.move = __bind(this.move, this);
    el.onclick = this.move;
  },
  move: function(){
    this.x += this.speed;
    console.log("Walking...");
  }
});

// Extend base class
var Tiger = Animal.extend({
  speed: 50
});

//Instantiate
var tony = new Tiger( document.querySelector('.tony-the-tiger') );

ES6 klasse

// Define Animal class
class Animal {
  constructor(el) {
    this.x = 0;
    el.onclick = this.move;
  }

  move() {
    this.x += this.speed;
    console.log("Walking...")
  }

  public speed = 10;
}

// Extend animal class
class Tiger extends Animal {
  public speed = 50;
}

// Instantiate
var tony = new Tiger( document.querySelector('.tony-the-tiger') );

CoffeeScript

Hvorfor og hvordan?

Hvem bruger CoffeeScript?



CoffeeScript klasse

# Helper to force a specific context in callbacks
__bind = (fn, me) ->
  return () -> 
    return fn.apply(me, arguments); 

# Define Animal class
class Animal
  speed: 10,
  constructor: (el) ->
    this.x = 0;
    el.onclick = this.move;
  move: () ->
    this.x += this.speed;
    console.log("Walking...");

# Extend Animal class
class Tiger extends Animal
  speed: 50

# Instantiate
tony = new Tiger( document.querySelector( '.tony-the-tiger' ) );

CoffeeScript syntax

 # Define Animal class
class Animal
  speed: 10
  constructor: (el) ->
    @x = 0
    el.onclick = @move
  move: =>
    @x += @speed
    console.log "Walking..."

# Extend Animal class
class Tiger extends Animal
  speed: 50

# Instantiate
tony = new Tiger document.querySelector '.tony-the-tiger'

Bliver til ...

 var Animal, Tiger, tony,
  __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

Animal = (function() {
  Animal.prototype.speed = 10;

  function Animal(el) {
    this.x = 0;
    el.onclick = this.move;
  }

  Animal.prototype.move = function() {
    this.x += this.speed;
    return console.log("Walking...");
  };

  return Animal;

})();

Tiger = (function(_super) {
  __extends(Tiger, _super);

  function Tiger() {
    return Tiger.__super__.constructor.apply(this, arguments);
  }

  Tiger.prototype.speed = 50;

  return Tiger;

})(Animal);

tony = new Tiger(document.querySelector('.tony-the-tiger'));

Arrow-funktioner

 someObject = {
  dynamicContext: ->
    # 'This' changes
  controlledContext: =>
    # 'This' is always someObject
}

"Literate programming"


CoffeeScript
foods = ['broccoli', 'spinach', 'chocolate']

eat food for food in foods when food isnt 'chocolate'

JavaScript
var foods, food, _i, _len;

foods = ['broccoli', 'spinach', 'chocolate'];

for (_i = 0, _len = foods.length; _i < _len; _i++) {
  food = foods[_i];
  if (food !== 'chocolate') {
    eat(food);
  }
}

Arrays i CoffeScript

Ranges
[10..1]
# => [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

Splats
numbers = [5,7,3]
min = Math.min numbers...
# => var min = Math.min(5, 7, 3);

Og meget mere ...



Source Maps

CoffeeScript og venner

Er CoffeeScript for alle?

Nyt syntax — Tager 2-4 timer at lære
Det er et sprog med holdninger
Der er andre midler (F.eks. Backbone, Angular, etc.)


Jens Ahrengot Boddum




Slides: slides.com/ahrengot/coffeescript/

Website:  ahrengot.com

Twitter: @ahrengot

LinkedIn: linkedin.com/in/ahrengot

CoffeeScript

By Jens Ahrengot Boddum

CoffeeScript

(Danish) A short walkthrough of the little language that reimagines JavaScript

  • 1,830