Tuesday, January 19, 2016

JavaScript Function: Overloading

Many object-oriented programming language supports Function Overloading: defining multiple functions with the same name and return value but with different parameters/arguments.

Let's use Java as an example:
public void displayName(String firstName){...}
public void displayName(String firstName, String lastName){...}
public void displayName(String firstName, Formatter format){...}
public void displayName(String firstName, String lastName, Formatter format){...}
JavaScript does not support function overloading because the type of the function parameters are not known hence there are cases where the signature of the function cannot be differentiated.

Let's use the following (invalid) example to describe why JavaScript does not support function overloading:
// Function with 1 parameter
function displayName(firstName){...};

// Function with 2 parameters, both are string, so far so good,
// JS engine can differentiate them (technically no, but let's just pretend)...
function displayName(firstName, lastName){...};

// Function with 2 parameters, but the second one is a method (or object)...
// JS Engine will not be able to differentiate the difference between
// lastName and formatter as the second parameter while JVM runtime
// knows based on the type information: 
// string for lastName and Formatter for formatter.
function displayName(firstName, formatter){...};
JavaScript engine will take the last function definition that exist in the code as the actual implementation, throwing out the previous function definition.

Even though JavaScript does not support function overloading, it doesn't mean JavaScript is unable to imitate the feature. This is when the Function arguments object shines.

The above Java implementation can be simplified to:
function displayName(firstName, lastName, customFormatter){
  if(arguments.length === 0){
    console.log("No parameter passed");
  }

  // Formatter is always the last one.
  var formatter;
  if(typeof arguments[arguments.length-1] === 'object'){
    formatter = arguments[arguments.length-1];
  }else{
    // let's assume DefaultFormatter exist.
    formatter = new DefaultFormatter();
  }

  var display = '';
  if(lastName && typeof lastName === 'string'){
    display = formatter.format("%s %s", firstName, lastName);    
  }else{
    display = formatter.format("%s", firstName);
  }

  console.log(display);
}

// only display first name using default formatter
displayName("John"); 

// only display first name with custom formatter
// imagine if the display follows Arabic: starts from Right to the Left
// instead of Left to Right like Roman...
displayName("John", new RightToLeftFormatter());

// display first and last name using default formatter
displayName("John", "Doe");

// display first and last name using VerticalFormatter
// imagine if the name is displayed vertically instead of horizontal ;)
displayName("John", "Doe", new VerticalFormatter());
From the above example, it appears that the JavaScript solution to imitate Function Overloading looks simpler compare to Java.

Monday, January 18, 2016

JavaScript Function: Parameters and Arguments


This article will cover JavaScript function parameters and arguments. Please refer to the previous article for an introduction to JavaScript Function.

Function Parameters

In JavaScript, a function declaration can have 0 to many parameters, for example:
// function body is excluded for brevity
function clear_dom() {...}      // function declaration with zero parameter
function display_car(car){...}  // function declaration with one parameter
function add(a,b){...}          // function declaration with two parameters
Function Arguments

The function arguments refer to the variables/values being passed into the function when it is invoked. For example:
// 1 and 2 are number literals being passed
// as arguments to the add() function
var result = add(1,2); 

// the {...} is an object literal being passed
// as arguments to the display_car() function
display_car({ make: "Honda", model: "Civic"}); 
Function Arguments variable

Within the function body, JavaScript provides implicit variable called "arguments". This implicit variable "arguments" refer to an object that contains a list of values being passed as function arguments to this function. This is very handy if the number of parameters are not known beforehand, for example:
function sum(){
  if(arguments === undefined) {
     return 0;
  }

  var result = 0;
  for(var i=0; i < arguments.length; i++) {
    result += arguments[i];
  }
  
  return result;  
}

var noResult = sum();           // noResult is 0
var sumResult = sum(1,2,3,4,5); // sumResult is 15
Note that while arguments function variable appears to look like an array, it is not an array object. Here's the defining characteristics of the arguments function variable:
  • It is an object
  • It derives from Object prototype (not array)
  • It looks like an array but it is not an array
  • It always exist within the function body
  • It scopes is Function Scope (once it leaves function, it's gone)
  • It has 2 properties: length and callee
    • length: refers to the number of arguments being passed
    • callee: refers to the method/function itself (in above example: sum() function)
Function Arguments Variable Optimization Killer

One note when it comes to Function arguments variable is that it must never be passed around to avoid "leak" (leak refers to optimization killer, not memory leak).
function leakOptimizationKiller(){
   return arguments;
} 

function leakOptimizationKiller(){
  var args = Array.prototype.slice.call(arguments);
}
The reason why this cancels out JS engine optimization is that the arguments variable is originally stored in the stack. In the above examples, JS engine is forced to create a reference of the arguments object in the heap as well.

Saturday, January 16, 2016

JavaScript Object: Array


JavaScript has a few built-in objects. One of the most-used objects is Array. Array stores a collection of ordered values that can be accessed via its index (a number).

Some of the characteristics of JavaScript array are as follows:
  • untyped (multiple types in the same array)
  • zero based, use 32-bit indexes
  • dynamic memory allocation (dynamically shrink or expand)
  • does not support multi-dimension (but can hold array of arrays)
  • sparse (can have gaps, multi-dimension can have varying length in the second dimension)
There are 2 ways to create an array: Array Literal and Array Constructor.

Array Literal

Array literal is the simplest and the most well-known way to cr// will throw Error, not a valid index numbereate an instance of an Array object in JavaScript and probably in most mainstream programming languages.
var arr = [];           // create an array with zero element
var arr = [1,2,3,4,5];  // create an array with 5 elements of the same type

// array with 5 elements: a number, an object, a string, a boolean, and an array
var arr = [1, {}, "This is a string", true, [1,2]]; 

// sparse array that contains 5 elements:
// a number followed by 3 undefined and ended with a number
var arr = [0, , , 3];
Array Constructor

Array constructor is probably less used and less well-known. It is also slower than Array literal.
var arr = new Array();           // create an array with zero elements
var arr = new Array(1,2,3,4,5);  // create an array with 5 elements, same type

// array with 5 elements: a number, an object, a string, a boolean, and an array
var arr = new Array(1, {}, "This is a string", true, new Array(1,2);

// sparse array that contains 5 elements: 
// a number followed by 3 undefined and ended with a number
var arr = new Array(0, , , 3);
Modifying Element, Accessing Element, How Many Elements?

Here are examples how to modify/access element of the array and also to know how many elements in the array:
// declare an array of 4 elements, all numbers
var arr = [1,2,3,4];

// modify the value of the first element
arr[0] = 5;

// how many items in the array currently
var arr_length = array.length;

// modify the value of the last element 
// (array index starts from 0, last element means n-1)
arr[arr_length - 1] = 10;

if(arr[1] + arr[2] === arr[0]){
  console.log("The sum of array index 1 and 2 are equal to array index 0");
}

// modifying length property of Array is allowed in certain situation

// Example #1: increase length from 4 to 10, 
// we'll have 6 undefined elements added to the end of the array
arr.length  = 10; 

// Example #2: decrease the length from 4 to 3
// hence arr[3] = 4 no longer exist, we reduce the size of array
arr.length  = 3; 

// Example #3: invalid index number
// will throw Error, not a valid index number
arr.length = -1; 
Iterating Array Elements

There are 2 ways to iterate over Array elements: for-loop and forEach array method.

1) Example for for-loop:
var arr = [1,2,3,4,5];

// NOTE: arr.length is evaluated at every iteration
for(var i=0; i < arr.length; i++){
  console.log("Index " + i + " : " + arr[i]);
}
2) Example for for-loop optimized:
var arr = [1,2,3,4,5];

// optimized because arr.length is called only once
for(var i=0, len; len = arr.length, i < len ; i++){
  console.log("Index " + i + " : " + arr[i]);
}
3) Example for forEach array method:
var arr = [1,2,3,4,5];

arr.forEach(function(element, index, array){
  console.log("Index " + i + " : " + element);
});

Sunday, January 10, 2016

JavaScript Function: Introduction


My previous article covered 1 out of 2 important concepts in JavaScript: Object. In this article, I will cover Function.

Function, in any programming language including JavaScript, contains a set of statements (or contains code) that will be executed when the function is invoked.

In JavaScript, functions are first-class object; they can have properties (those key-value pairs) just like object as well. The thing that separates function with object is that function can be executed (as it contains code).

Here's the defining characteristics of function:
  • has properties just like object
  • executable
  • has an internal property [[Call]]
    • internal properties are not exposed to the public in any way
    • Because of [[Call]] internal property, typeof operator knows this is a function

There are 2 forms of function in JavaScript: function declaration and function expression.

Function Declaration
function print_car(car){
  console.log("Car Make: " + car.make);
  console.log("Car Model: " + car.model);
}
var car = { make: "Honda", model: "Civic" };
print_car(car);
Rule for function declaration:
  • function name (e.g.: print_car) is required
  • function starts with { and ends with }
  • semicolon to terminate the function declaration is not needed
  • function parameter (e.g.: car) is optional
Function Expression
var display = function(car){
  console.log("Car Make: " + car.make);
  console.log("Car Model: " + car.model);
};

var car = { make: "Honda", model: "Civic" };
display(car);
Rule for function expression:
  • function name is optional (although recommended)
  • function starts with { and ends with }
  • semicolon must exists after the closing curly braces (})
  • function parameter (e.g.: car) is optional
  • function is to be stored to a variable for referencing purpose
The above function (created using the function expression technique) is also known as anonymous function: you cannot refer to the function itself, you can only refer to the function via the variable that holds the function.

Notice that the function is stored in a variable. This is doable in JavaScript because a function is an object. Since we can store a reference to an object in a variable, we can do the same with function as well: storing a reference to a function in a variable.

Function Return Value

In JavaScript, function always have a return value. This could be confusing or even weird when compare to other programming languages like Java/C/C++/C#. The above examples returns undefined:
var returnValue = print_car({ make: "Honda", model: "Civic" });
console.log(returnValue); // this will print "undefined"
If the last statement of the function is a return keyword followed by a variable or literal value, then the function will return the value of the variable or the literal value itself.
function add(left, right){
  return left + right;
};
var result = add(1,2); // should return 3
Function as Object method
If a function is a property of an object, the function is now known as a method object.
var car = {
  make: "Honda",
  model: "Civic",
  display: function display(){
     // this refers to the current object: car
     console.log("Car Make: " + this.make);
     console.log("Car Model: " + this.model);
  };
};

car.display();

Saturday, January 9, 2016

JavaScript Object: Introduction


There are 2 very important concept in JavaScript: Object and Function. This tutorial will cover JavaScript Object.

Object, in JavaScript, can be viewed as a container that stores a collection of values. Object can store both primitive values and object values.

The following are some characteristics of an object:
  • key-value pair
    • key can be either string or number
    • value can either be a primitive value or object value
    • key is known as "property"
  • mimic known data structure: "hash", "hashtable", "dictionary", "map"
  • dynamic
    • property can be added at any time
    • property can be removed at any time
There are 3 ways to create an object in JavaScript: 

Creating an object: object literal
var car = {
  make : "Honda",
  model: "Civic",
  attributes: {
     doors: 4,
     passengers: 5 // comma not needed here to end the key-value pair
  } // comma not needed here to end the key-value pair
};
Rules for object literal creation: 
  • Starts with { and ends with };
  • key followed by colon followed by its value and a comma (unless it is the last key-value pair)

Creating an object: new keyword
var car = new Object();
car.make = "Honda";
car.model = "Civic";
car.attributes = new Object();
car.attributes.doors = 4;
car.attributes.passengers = 5;
Rules for new keyword object creation:
  • Use the keyword new
  • Use a "special" function (in this case, Object) known as "constructor"
  • Add key-value pairs one by one
    • these pairs can also be initialized inside the constructor just like in mainstream Object Oriented programming languages

Creating an object: Object.create()
var car = Object.create(Object.prototype,{
  make: { value: "Honda" },
  model: { value: "Civic" },
  attributes: { 
    value: Object.create(Object.prototype,{
      doors: { value: 4 },
      passengers: { value: 5}
    })
  }  
});
Rules for Object.create() object creation:
  • Use "static" method "create()" of Object.
  • First parameter: the prototype object that the new object will be based on
  • Second parameter: an object that define the properties attributes, in this particular example, we initialized its "value" attribute (more detail in another blog post)

When to use each technique of Object creation

Use object literal technique when:
  • you need a one-off data structure (similar to C-struct) on-the-fly (not a template)
  • you need a simple singleton-like object (unfortunately a mutable singleton)

Use new keyword when:
  • you need an instance of an object (analogous with mainstream OOP language like Java or C#)
  • you need multiple instances of a type of an object with different values
  • more details will be covered in another article that covers "prototype" as well.

Use Object.create() when:
  • you need more control over the property attributes (will be covered in another article) of the newly created instance of an object
  • for example: set the car.make property to be read-only (can only read, but can't modify)

Accessing and Modifying properties

There are 2 ways to access/modify a property of an object (assuming the property can be accessed and modified): dot notation or square bracket notation.

Dot Notation example:
console.log(car.make); // "Honda"
car.make="Toyota";
console.log(car.make); // "Toyota"
Square Bracket example:
console.log(car["make"]); // "Honda"
car["make"]="Toyota";
console.log(car["make"]); // "Toyota"

When to use each technique of Accessing/Modifying properties

Use dot notation when:

  • any time you can
  • know the property name before hand

Use square bracket when:

  • property name is pre-computed or pre-calculated during run-time
  • creating an object that maps a range of keys/properties to a set of values
    • for example, mapping A-Z or 0-9 to a set of values

Using Number as Key/Property Name

Technically it is legal to use number or a string representation of number as the key/property name but in general, try not to as it may tricked people to think that the object type is an array.

For example:
var one = { 1 : "One" }; 
var two = { "2": "Two" };
console.log(one[1]);  // "One"
console.log(one["1"]); // "One"
console.log(two[2]); // "Two"
console.log(two["2"]); // "Two"

// The following will throw SyntaxError error,
// a number is not a legal identifier
console.log(one.1);
console.log(two.2);

Summary

An object is an aggregate of property-value pairs. There are 3 ways to create an instance of an object in JavaScript. Each technique is useful in certain situations. There are 2 ways to access or modify the property value. In JavaScript, the key/property name can be a number.