Saturday, March 01, 2014

JavaScript Function Invocation and “this”

Understanding JavaScript Function Invocation and “this” « Katz Got Your Tongue?:
by Yehuda Katz, a member of the Ember.js, Ruby on Rails and jQuery Core Teams





JavaScript Patterns

Excellent an practical class:
Structuring JavaScript Code - Online Training Course for Developers:
by Dan Wahlin @ Pluralsight

Output: <div id="output"></div>
<script>
var output = document.getElementById("output");

function nonClosure1() {
  var date = new Date();
  return date.getMilliseconds();
}

output.innerHTML = nonClosure1();
window.setTimeout(function () {
  output.innerHTML += ' # ' + nonClosure1();
}, 500); // different value after .5 seconds

// Closure

function closure2() {
  var date = new Date(); // "private
  return function() { // "public", closure around "date"
    return date.getMilliseconds();
  }
}

var closure = closure2(); // assign value to date
output.innerHTML = closure();
window.setTimeout(function () {
  output.innerHTML += '|' + closure();
}, 500); // same value after .5 seconds

// Module Pattern

var Calculator = function (id) { 
  // uppercase convention, to be initiated with 'new'
  var elem = document.getElementById(id); // private
  return { // public 
    add: function (x, y) {
      var val = x + y;
      elem.innerHTML = val;
    }
  };
};

var calc = new Calculator('output');
calc.add(2, 2);

// Revealing Module Pattern

var calculator = function (id) { 
  var elem = document.getElementById(id), // private
  doAdd = function (x, y) { // private
    var val = x + y;
    elem.innerHTML = val;
  };
  return {
    add: doAdd // public alias for private function  
  }; 
};

var calc = calculator('output');
calc.add(2, 2);

// Singleton Pattern

var calculator = function (id) { 
  var elem = document.getElementById(id), 
  doAdd = function (x, y) {
    var val = x + y;
    elem.innerHTML = val;
  };
  return {
    add: doAdd 
  }; 
}('output'); // create single instance 

calculator.add(2, 2);

// Prototype Pattern

var Calculator = function (id) { // uppercase, needs 'new'
  this.elem = document.getElementById(id); // "instance" 
};

Calculator.prototype = { // "class", shared, non-state
  add: function (x, y) { // public
    var val = x + y;
    this.elem.innerHTML = val;
  }
};

var calc = new Calculator('output');
calc.add(2, 2);

// Revealing Prototype Pattern

var Calculator = function (id) {
  this.elem = document.getElementById(id); // "instance"
};

Calculator.prototype = function () {
  var myAdd = function (x, y) { // private, shared 
    var val = x + y;
    this.elem.innerHTML = val;
  };
  return { // public members
    add: myAdd
  };
}(); // self invoking function

var calc = new Calculator('output');
calc.add(2, 2);

// Namespace Pattern

// use existing object if already created, or create new; 
var myNS = myNS || {}; 

myNS.Calculator = function (id) {
  this.elem = document.getElementById(id);
};

myNS.Calculator.prototype = {
  add: function (x, y) {
    var val = x + y;
    this.elem.innerHTML = val;
  }
};

var calc = new myNS.Calculator('output');

calc.add(2, 2);

</script>