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");

Friday, December 30, 2016

JavaScript Evolution ESMAScript 6 - Promises

Typically, to avoid blocking the main thread of execution, we write non-blocking code using asynchronous style function pass callback like this:
getResult("Saas", function(result) {
  ui.renderSidebar(results);
}
When nested callbacks start to grow, our code becomes harder to read. We have to check for error on every callback.
getResultFromServer("Saas", function(error, results) {
  if (error) { // handle error };
  ui.renderSideBar(results, function(error, results) {
    if (error) { //handle error };
    sendNotificationToServer(results, function(error, response) {
      if (error) { // handle error };
      doSomethingElse (response, function(error)) {
        if (error) { //handle error };
        //...
      };
    };
  };
});
Promises brought to JavasScript trying to offer a solution to this issue by bringing new abstraction that allows us to write asynchronous code in an easier way.
getResultFromServer("Saas")
  .then(ui.renderSidebar)
  .then(sendNotificationToServer)
  .then(doSomethingElse)
  .catch(function(error) {
    console.log("Error :" + error);
  }
The Promise constructor function takes an anonymous function with 2 callback argument known as handles. Handles are responsible for resolving or rejecting the Promise.

Create a new Promise automatically set it to the pending state. Then, it can become fulfilled(resolve) or rejected(reject).

One thing to remember is that Promise not return a result, its return a future value, such as the eventual result if asynchronous operation.

Let's wrap the XMLHttpRequest object API within a Promise. Calling the resolve() handler moves the Promise to a fulfilled state. We'll call the reject() handler for unsuccessful status codes and also when the error event is triggered on our request object. Both move the Promise to a rejected state.
function getResultFromServer(pollName){
  return new Promise(function(resolve, reject) {
    request.onload = function() {
      if (request.status >= 200 && request.status < 400) {
        resolve(request.response);
      } else {
        reject(new Error(request,status));
      };
    };
    request.oneerror = function() {
      reject(new Error ("Error Fetching Results"));
    };
  };
};
We can use then() method to read results from the Promise once resolved. We can chain multiple calls to then(). The return value from 1 call is passed as an argument to the next.

Once an error occurs, execution moves immediately to the catch() function. None of the remaining then() function are invoked.
getResultFromServer("Saas")
  .then(function(result){
    // Return value to next then().
    return result.filter((result) => result.city === "Orlado");
  })
  .then(function(resultFromOrlando){
    ui.renderSideBar(resultsFromOrlando);
  })
  .catch(function(error) {
    console.log("Error : " + error);
  })

Friday, December 23, 2016

JavaScript Evolution ESMAScript 6 - Module

In this section, we learn about using Module to encapsulate classes.

To export classes, use the export syntax with the class name inside curly braces.

flash-message.js
class FlashMessage {

  constructor(message) {
    this.message = message;
  }

  renderAlert() {
    alert(`${this.message} from alert`);
  }

  renderConsole() {
    console.log(`${this.message} from log`);
  }

}

export {FlashMessage} // Export class to outside world.
To import the class, we must use the same export name.

app.js
import {FlashMessage} from './flash-message';

let flash = new FlashMessage('Hello');
flash.renderAlert(); // Alert -> Hello from alert
flash.renderConsole(); // Console -> Hello from log