Search

A-Z of JavaScript


Here is an A - Z list of some Javascript idioms and patterns. The idea is to convey in simple terms some features of the actual Javascript language (rather than how it can interact with DOM). Enjoy... 

Array Literals
An array literal can be defined using a comma separated list in square brackets.
 
var months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun',
'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
console.log(months[0]); // outputs jan
console.log(months.length) // outputs 12

Arrays in javascript have a wide selection methods including push() and pop().  Suppose the world got taken over by a dictator who wanted to get rid of the last month of the year? The dictator would just do...
 
months.pop();
And of course, the dictator will eventually want to add a month after himself when everyone will have to worship him: 
months.push("me");

Callbacks
Since functions are objects, they can be passed as arguments to other functions.
function peakOil(callback) {
//... code
callback();  // the parentheses mean the function is executed!
}

function changeCivilisationCallback(){
//...
}

// Now pass the changeCivilisationCallback to peakOil.
// Note: no changeCivilisationCallback parentheses because it is not
// executed at this point.
// It will be excuted later inside peak oil.
peakOil(changeCivilisationCallback);
In the example above, the chanceCivilisationCallback callback function is invoked by peakOil. Logic could be added to check if the energy returns from solar panels and wind farms were sufficient in which case another callback, other than changeCivilisationCallback could be added. 

Configuration Object 
Instead of passing around a bunch of related properties...
 
function addCar(colour, wheelsize, regplate) {...}
Use a configuration object 
function addCar(carConf) {...}

var myCarConf = {
colour: "blue",
wheelsize: "32",
regplate: "00D98788"
};
addCar(myCarConf);
The use of a configuration object makes it makes it easier to write clean APIs that don't need to take a huge long list of parameters. They also means you are less likely to get silly errors if parameters are in the wrong order. 
Closures
There are three ways to creats objects in Javascript: using literals, using the constuctor function and by using a closure.  What closures offer that the other two approaches do not is
 encapsulation.  Closures make it possible to hide away functions and variables. 
var counter = function(count) {
console.log(">> setting count to " + this.count);
return {
getCount: function(){
return ++count;
}
}
}

mycounter = counter(0);
console.log(mycounter.getCount());  // outputs 1
console.log(mycounter.getCount());  // outputs 2
console.log(mycounter.getCount());  // outputs 3
console.log(mycounter.getCount());  // outputs 4

// Same again with offset this time.
mycounterWithOffset = counter(10);
console.log(mycounterWithOffset .getCount());  // outputs 11
console.log(mycounterWithOffset .getCount());  // outputs 12
console.log(mycounterWithOffset .getCount());  // outputs 13
console.log(mycounterWithOffset .getCount());  // outputs 14

Note: The closure is the object literal returned from annoymous function. It "closes" over the count variable. No-one can access it except for the closure. It is encapsulated. The closure also has a sense of state. Note also how the it maintains the value of the counter.
  

Constructor Functions (Built in) 
There are no classes in Javascript but there are construtor functions which use the
 new keyword syntax similar to the class based object creation in Java or other languages. Javascript has some built-in constructor functions. These include Object(), Date(), String() etc. 
var person = new Object();  // person variable is an Object
person.name = "alex";  // properties can then be dynamically added

Constructor Functions (Custom) 
When a function is invoked with the keyword
 new, it is referred to as a Constructor function. The newmeans that the new object will have a hidden link to value of the function's prototype member and thethis keyword will be bound to the new object. 
function MyConstrutorFunction() {
this.goodblog = "dublintech.blogspot.com";
}

var newObject = new MyConstrutorFunction();
console.log(typeof newObject);    // "object"
console.log(newObject.goodblog);  // "dublintech.blogspot.com"

var noNewObject = MyConstrutorFunction();
console.log(typeof noNewObject);  // "undefined"
console.log(window.tastes);       // "yummy"
The convention is that constructor functions should begin with a capital letter. Note: if the new keyword is not used, then the 'this' variable inside the function will refer to the global object. Can you smell a potential mess? Hence why the capital letter convention for constructor functions is used. The capital letter means: "I am a constructor function, please use the new keyword". 

Currying 
Currying is the process of reducing the number of arguments passed to a function by setting some argument(s) to predefined values. Consider this function.
 
function outputNumbers(begin, end) {
var i;
for (i = begin; i <= end; i++) {
print(i);
}
}
outputNumbers(0, 5);  // outputs 0, 1, 2, 3, 4, 5
outputNumbers(1, 5);  // outputs 1, 2, 3, 4, 5
Suppose, we want a similar function with a fixed "begin" value. Let's say the "begin" value was always  We could do: 
function outputNumbersFixedStart(start) {
return function(end) {
return outputNumbers(start, end);
}
}
And then define a variable to be this new function... 
var outputFromOne = outputNumbersFixedStart(1);
outputFromOne(3);  1, 2, 3
outputFromOne(5);  1, 2, 3, 4, 5

Delete Operator
The delete operator can be used to remove properties from objects and arrays.
var person = {name: 'Alex', age: 56};
// damn I don't want them to know my age remove it
delete person.age;
console.log("name" in person);  // outputs true because it is still there
console.log("age" in person);   // outputs false


var colours = ['red', 'green', 'blue']
// is red really in the array?
console.log(colours.indexOf('red') > -1);  // outputs true.
// remove red, it's going out of fashion!
delete colours[colours.indexOf('red')];
console.log(colours.indexOf('red') > -1);  // outputs false
console.log(colours.length) // length is still three, remember it's javascript!

You cannot delete global variables or prototype attributes.
 
console.log(delete Object.prototype)  // can't be deleted, outputs false
function MyFunction() {
// ...
}
console.log(delete MyFunction.prototype) // can't be deleted, outputs false

var myglobalVar = 1;
console.log(delete this.myglobalVar)   // can't be delete, outputs false


Dynamic Arguments 
Arguments for a function do not have to be specifed in the function definition
 
function myFunction(){
// ... Note myfunction has no arguments in signature
for(var i=0; i < arguments.length; i++){
alert(arguments[i].value);
}
}

myFunction("tony", "Magoo");  // any argument can be specified
The arguments parameter is an array available to functions and gives access to all arguments that were specified in the invocation. 

for-in iterations
for-in loops (also called enumeration) should be used to iterate over nonarray objects.
var counties = {
dublin: "good",
kildare: "not bad",
cork: "avoid"
}

for (var i in counties) {
if (counties.hasOwnProperty(i)) { // filter out prototype properties
console.log(i, ":", counties[i]);
}
}

Function declaration
In a function declaration, the function stands on its own and does not need to be assigned to anything.
function multiple(a, b) {
return a * b;
// Note, no semi colon is needed

Function expressions
When function is defined as part of something else's definition, it is considered a function expression. 
 
multiply = function multiplyFunction(a, b) {
return a * b;
}; // Note the semi colan must be placed after the function definition

console.log(multiply(5, 10)); // outputs 50

In the above example, the function is named.  It can also be anonymous, in which case the name property will be a blank string.
multiply = function (a, b) {
return a * b;
// Note the semi colan must be placed after the function definition

console.log(multiply(5, 10)); // outputs 50

Functional Inheritance
Functional inheritance is mechanism of inheritance that provides encapsulation by using closures. Before trying to understand the syntax, take an example first. Suppose we want to represent planets in the solar system. We decided to have a
 planet base object and then several planet child objects which inherit from the base object. Here is the base planet object: 
var planet = function(spec) {
var that = {};
that.getName = function() {
return spec.radius;
};
that.getNumberOfMoons()= function() {
return spec.numberOfMoons;
};
return that;
}
Now for some planets. Let's start with Earth and Jupiter and to amuse ourselves let's add a function for Earth for people to leave and a function to Jupiter for people arriving. Sarah Palin has taken over and things have got pretty bad!!!
var earth = function(spec) {
var that = planet{spec};   // No need for new keyword!
that.peopleLeave = function() {
// ... people leave
}
return that;
}

No comments:

Post a Comment