Thursday, January 19, 2017

JavaScript: Module Pattern with Anonymous Closure

Most developers create module JavaScript only with Public properties.
var ARMORY = {
  weaponList : [ * List of weapon object * ],
  removeWeapon : function(...){},
  replaceWeapon : function(...){},
  makeArmorRequest : function(...){}
};
Above module has a bunch of public variables and methods which can still be accessed by any code that know the name of the space and its properties.

What if we wanted some stuff to be accessible only to the module? Some privacy? This can be easily accomplished by wrap the entire set of properties in an anonymous immediately invoked function expression (IIFE).
var ARMORY = (function(){

  // Private
  var weaponList = [ * List of weapon object * ];
  var removeWeapon = function(...){};
  var replaceWeapon = function(...){};

  // Public
  return{
    makeArmorRequest: function(...){}
  }

})();
With IIFE, you can only have a single instance and you can call the instance without New. E.g.:
ARMORY.makeArmorRequest();

JavaScript: Ternary Conditional

Some simple conditionals take a lot of code to choose on assignment.
let isAuthor = false;
let weapon;

if (isAuthor) {
  weapon = "Exalibur";
} else {
  weapon = "Longsword";
};
Let's use a syntax trick to make this more concise!

The ternary conditional provides a shortcut over lengthier conditional blocks. Ternary conditional syntax:
someCondition ? pickThisIfTrue : pickThisIfFalse ;
Let's turn our lengthy conditional example to ternary conditional.
let isAuthur = false;
let weapon = isAuthor ? "Exalibur" : "Longsword";

JavaScript: Loop Optimazation

Here are the common For loop scenario.
let data = {name:["Simon", "Alvin", "Sharmal"]};

for(let i=0; i<data.name.length; i++){
  console.log(data,name[i]);
};
This is not  the best way because, at the start of each potential loop cycle, the program will need to find and retrieve:
  1. the value of i
  2. the data object
  3. the name property
  4. the array pointed by the property
  5. the length property of the array
We can use "caches values" to curtail lengthy, repetitive access to the same data.
let data = {name:["Simon", "Alvin", "Sharmal"]};

for(let i=0, x= data.name.length; i<x; i++){
  console.log(data,name[i]);
};
Memory access during loop control now only needs to:
  1. retrieve the value of i
  2. retrieve the value of x

JavaScript: Short Performance Tips

1. Use a document fragment to insert additional all at once.
  • Each new addition to the DOM causes document "reflow", which can really hinder user experience.
  • Fragments are invisible containers that hold multiple DOM elements without a node.

Bad Performance
let list = document.getElementById("kotwList");
let kotw = ["Simon","Alvin","Melvin","Shelman"];
for(let i=0, x=kotw.length; i < x; i++){
  var element=document.createElement("li");
  element.appendChild(document.createTextNode(kotw[i]));
  list.appendChild(element);
}

Good Performance
let list = document.getElementById("kotwList");
let kotw = ["Simon","Alvin","Melvin","Shelman"];
let fragment = document.createDocumentFragment();

for(let i=0, x=kotw.length; i < x; i++){
  var element=document.createElement("li");
  element.appendChild(document.createTextNode(kotw[i]));
  fragment.appendChild(element);
}

list.appendChild(fragment); // Only one DOM touch.

2. Declare variable as few times as possible. 
  • Every var keyword adds a lookup for the JavaScript parses that can be avoided with common extension.

Bad Performance
var name;
var age;
var birthday;

Good Performance
var, name, age, birthday;

Wednesday, January 18, 2017

JavaScript: Measuring Performance

You can test the speed of your code using console.time([label]) and console.timeEnd([label]).

Example:
console.time("SpendTest");
for(let i=0; i<100; i++){
  console.log(i);
};
console.timeEnd("SpendTest");