Sundarrajk's Weblog

Archive for the ‘JavaScript – The Good Parts’ Category

JavaScript – The Good Parts – Part 7

This is the last and final post based on the book JavaScript – The Good Parts by Douglas Crockford. In this post, as in the previous post, we will continue with some more methods in the pre-defined objects of JavaScript.

RegExp

regexp.exec(string) The exec is the most powerful (and the slowest) of all methods that use regular expression. If it successfully matches the regexp and the string, it returns an array. The “0” element of the array will contain the substring that matched the regexp. The 1 element is the text captured by the group 1, the 2 element is the text captured by group 2, and so on. If the match fails it will return a null.
If the regexp has a “g” flag, things are a little complicated. The searching begins not at the position 0, but at the position regexp.lastIndex (which is initially zero). If the match is successful then the regexp.lastIndex will be set to the position of the first character after the match. An unsuccessful match resets the regexp.lastIndex to 0.

regexp.test(string) This is the simplest and the fastest of the methods that use regular expression. If the regexp matches the string it returns true, otherwise it returns false. Do not use “g” flat with this method.
var b = /&.+;/.test(‘frank & beans’); //b is true.

String

string.charAt(pos) This returns the character at the position “pos” in this string. If pos is less than zero or greater than or equal to the length of the string, it returns an empty string.
var name = ‘Curly’;
var initial = name.chartAt(0); //initial is “C”

string.charCodeAt(pos) This returns an integer representation of the character at position “pos” instead of the character. If pos is less than zero or greater than or equal to the length of the string, it returns a NaN.
var name = “Curly”;
var initial = name.chartCodeAt(0); //initial is “67”

string.concat(string …) This method makes a new string by concatenating the other strings together.
var s = ‘C’.concat(‘a’, ‘t’); //value of c is “Cat”

string.indexOf(searchString, position) This searches for the “searchString” from “position” in the string. This returns a -1 if this string is not found, else it returns the index at which the searchString is found.
var text = “Mississippi”;
var p = text.indexOf(‘ss’); //p is 2
p = text.indexOf(‘ss’, 3); //p is 5
p = text.indexOf(‘ss’, 6); //p is -1

string.lastIndexOf(searchString, position) This searches for the “searchString” from “position” in the string but in the reverse direction. This returns a -1 if this string is not found, else it returns the index at which the searchString is found.
var text = “Mississippi”;
var p = text.lastIndexOf(‘ss’); //p is 5
p = text.lastIndexOf(‘ss’, 3); //p is 2
p = text.indexOf(‘ss’, 6); //p is 5

string.localeCompare(that) This compares two string and returns a -1 if the “this” string is smaller than the second, 0 if they are equal and 1 if the “this” string is greater than the second.
var m = [‘AAA’, ‘A’, ‘aa’, ‘a’, ‘Aa’, ‘aaa’];
m.sort(function (a, b) {
  return a.compareLocale(b);
});

//m in some locale after sorting is [‘a’, ‘A’, ‘aa’, ‘Aa’, ‘aaa’,  ‘AAA’];

string.match(regexp) This matches a string and a regular expression. How it does depends on the “g” flag. If no “g” flag is specified then the result of calling string.match(regexp) is same as calling regexp.exec(string). However if the regexp has the “g” flag, then it produces an array of all the matches, but excludes capturing groups.

string.replace(searchValue, replaceValue) The replace method searches the string for occurrence of “searchValue” and replaces them with “replaceValue”. The “searchValue” can be a regular expression object. If it is a string then only the first occurrence of searchValue is replaced.
If the searchValue is a regular expression and it has the “g” flag then all the occurrences will be replaced. If it does not have a “g” flag then only the first occurrence will be replaced.
The replaceValue is a string then the character $ has a special meaning.
//Capture 3 digits within parenthesis
var oldareacode = /\((\d{3})\)/g;
var p = ‘(555)666-1212’.replace(oldareacode, ‘$1-‘); //p is 555-666-1212

Dollar Sequence Replacement
$$ $
$& The matched text
$number Capture group text
$` The text preceding the match
$’ The text following the match

If the replaceValue is a function, it will be called for each match, and the string returned by the function will be used as the replacement text. The first parameter passed to the function is the matched text. The second parameter is the text of the capture group 1, the next parameter is of group 2 and so on.

string.search (regexp) This is like the indexOf method except that it takes a regexp. If “g” parameter, if passed is ignored.

string.slice(start, end) This is like the array slice. It returns the string value from the start to the end -1 position. If the start parameter is negative, it adds string.length to it.  If no end parameter is specified then it is taken to be string.length. If the end parameter is negative it adds the string.length to it.
var text = ‘and in it he says “Any damn fool could’;
var a = text.slice(18); //a is ‘”Any damn fool could’
var b = text.slice(0, 3); //b is ‘Any’
var c = text.splice(-5); //c is ‘could’
var d = text.slice(19,32); //d is ‘Any damn fool’
var e = text.slice(19, -5); //d is ‘Any damn fool ‘

string.split(separator, limit) The split method creates an array of strings by splitting this string into pieces. The optional limit parameter can limit the number of pieces that will be split. The separator parameter can be a string or a regular expression.
If the separator is the empty string, an array of single characters is produced.
var digits = ‘0123456789’;
var a = digits.split(”, 5); //a is [‘0’, ‘1’, ‘2’, ‘3’, ‘456789’];
Otherwise the string is searched for all occurrences of the separator. Each unit of text between separators is copied into the array. The “g” flag is ignored.
var ip = “192.168.32.45”;
var b = ip.split(‘.’); //b is [‘192’, ‘168’, ’32’, ’45’];
var c = ‘|a|b|c|’.split(‘|’); //c is [”, ‘a’, ‘b’. ‘c’, ”];

string.substring(start, end) This is same as the slice method except it does not adjust for negative values.

string.toLocaleLowerCase() Converts the string to a lower case based on the locale.

string.toLocaleUpperCase() Converts the string to an upper case based on the locale.

string.toLowerCase() Same as toLocaleLowerCase() but without considering the locale.

string.toUpperCase() Same as toLocaleUpperCase() but without considering the locale.

string.fromCharCode(char …) The converts a series of numbers to a string.
var a = String.fromCharCode(67, 97, 116); // a is ‘Cat’

Conclusion JavaScript is a very powerful language and it has its good parts. It also has its dark side, like the global variables, but if one takes the trouble to learn and understand the language then one can work wonders with this language.

To end the series here is a series of blogposts by Venkat Subramanian which will serve as a very good introduction to functional programming for the uninitiated.
http://blog.agiledeveloper.com/2012/11/functional-style-of-programming-in_14.html
http://blog.agiledeveloper.com/2012/11/functional-style-of-programming-in_15.html
http://blog.agiledeveloper.com/2012/11/functional-style-of-programming-in_16.html
http://blog.agiledeveloper.com/2012/11/functional-style-of-programming-in.html

This is the penultimate posting in this series of posts based on the book JavaScript – The Good Parts by Douglas Crockford.
The previous post covered how to “curry” functions and some JavaScript gotchas.
This post gives a list of pre-built methods in the standard objects pre-defined in JavaScript. Many of these would be known only to the hardcore users of JavaScripts and this is serve as an eye-opener to the casual users of JavaScript.

Array
array.concat(items)
This method appends the items to the base array. If the items itself is an array that elements of that array are copied to that of the base array.
E.g.
var a = [‘a’, ‘b’, ‘c’];
var b = [‘d’, ‘e’, ‘f’];
var c = a.concat(b, true);
//c is [‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, true];

array.join(separator)
This joins the elements in an array separated by the separator and gives a String.
var a = [‘a’, ‘b’, ‘c’];
var c = a.join(“/”);  //c is ‘a/b/c/’

array.pop
This removes the last element from the array and returns this as the value. The size of array reduces by one.
var a = [‘a’, ‘b’, ‘c’];
var c = a.pop();
//c = ‘c’ and a =[‘a’, ‘b’];

array.push(item …)
This adds the object to the end of the array.
var a = [‘a’, ‘b’, ‘c’];
var b = [‘d’, ‘e’, ‘f’];
var c = a.push(b, true);
//c is [‘a’, ‘b’, ‘c’, [‘d’, ‘e’, ‘f’], true];
Note how this is different from concat. The array “b” has been embedded at index 3 of the array “a”. It has not copied the contents of array “b” to “a”.

array.reverse()
This reverses the values in the array.
var a = [‘a’, ‘b’, ‘c’];
var b = a.reverse();
//both a and b will be [‘c’, ‘b’, ‘a’]

array.shift()
The shift method removes the first element from an array and returns it. If the array is empty it returns undefined.
var a = [‘a’, ‘b’, ‘c’];
var b = a.shift();
//b is ‘a’ and a is [‘b’,’c’]

array.slice(start, end)
This is like substring. Where start is the start position and end is the last but one position that should be copied. If none is specified then it is copied to the end of the array.
var a = [‘a’, ‘b’, ‘c’];
var b = a.slice(0,1); //b will be [‘a’];
var c= a.slice(1); //c will be [‘b’, ‘c’]
var d = a.slice(1, 2); //d will be [‘b’]

array.sort(comparefn)
This sorts the array assuming that all the elements are string. If one needs to sort based on some other datatype one can pass a compare function. This function will be passed the two consecutive values and it should return a “-1” if the first is less than the second a “0” if they are equal and a “1” if the first is greater than the second for sorting the elements in an ascending fashion.

array.splice(start, deleteCount, item, …)
This method starts deleting “deleteCount” elements from the “start” position and inserts the values in item into this gap.

array.unshift(item …)
The unshift method is like the push method, except that it pushes the items onto the front of the array instead of at the end. It returns the array’s new length.
var a = [‘a’, ‘b’, ‘c’];
var r = a.unshift(‘?’, ‘@’);
//a is [‘?’, ‘@’ ,‘a’, ‘b’, ‘c’];
//r is 5

Function
function.apply(thisArg, arguments)
This executes the function with “thisArg” treated as the “this” for the function and the “arguments” is passed as the “arguments” to the function.

Number
number.toExponential(fractionDigits)
This converts this number to a string in the exponential form. The optional fractionalDigits controls the number of decimal places. This should be between 0 and 20.
Math.PI.toExponential(0) = 3e+0
Math.PI.toExponential(2) = 3.14e+0
Math.PI.toExponential(7) = 3.1415927e+0
Math.PI.toExponential(16) = 3.1415926535897930e+0
Math.PI.toExponential() = 3.141592653589793e+0

number.toFixed(fractionDigits)
This method converts this number to a string in the decimal form. The optional fractionDigits parameter controls the number of decimal places. It should be between 0 and 20. The default is 0.
Math.PI.toFixed(0) = 3
Math.PI.toFixed(2) = 3.14
Math.PI.toFixed(7) = 3.1415927
Math.PI.toFixed(16) = 3.1415926535897930
Math.PI.toFixed() = 3

number.toPrecision(precision) This converts the number to a string in decimal form. The optional precision parameter controls the number of digits of precision. It should be between 1 and 21.
Math.PI.toPrecision(2) = 3.1
Math.PI.toPrecision(7) = 3.141593
Math.PI.toPrecision(16) = 3.141592653589793
Math.PI.toPrecision() = 3.141592653589793

number.toString(radix) This converts the number to string. The optional radix parameter controls the radix or the base. This should be between 2 and 36. The default radix base is 10.
Math.PI.toString(2) = 11.001001000011111101101010100010001000010110100011
Math.PI.toString(7) = 3.1103755242102643
Math.PI.toString(16) = 3.243f6a8885a3
Math.PI.toString() = 3.141592653589793

Object
object.hasOwnProperty(name)
This indicates if the property by the specified “name” belongs the object or is it derived from the one of the prototype objects in the hierarchy.
var a = {member: true};
var b = Object.beget(a); //b uses a as the prototype
var t = a.hasOwnProperty(‘member’); //”t” is true
var f = b.hasOwnProperty(‘member’); //”f” is false
var v = b.member; //“v” is true.

Introduction

This is the fifth post based on the book JavaScript – The Good Parts by Douglas Crockford. The previous post covered details like Closures and Modules. This section covers Curry, some Gotcha in JavaScript, Exceptions and With.

Curry

This allows one to create a new function using an existing function with one or more arguments having a specific value.
Setup the curry function

Function.method ('curry', function () {
var slice = Array.prototype.slice, args = slice.apply(arguments), that = this;
return function () {
return that.apply(null, args.concat(slice.apply(arguments)));
};
});

Now use this as follows:

var add = add.curry(1);
add1(6); //returns 7

In this manner we can create new functions from existing functions by providing value to one or more of the arguments.

Gotcha

JavaScript does not require one to put a semicolon, but this can lead to some unexpected surprises. Consider this function.

a = function () {
return
{
ok: false;
};
}

One expects this method to return an object with an attribute “ok” with value “false”. But what this actually returns is “undefined”. This happens because of the way JavaScript introduces “;”. Since there is no semicolon after the keyword “return”, JavaScript will put a semicolon after “return” and return “undefined”. The rest of the code is ignored.

Converting Strings to Integers

One way to convert String values to integers is to use parseInt(. The other way to do this would be to compute as follows:

X = 3 + (+"4"); //X = 7
X = 3 + "4"; //X = 34

Exceptions

JavaScript can throw Exception in case of errors. The following are the type of exceptions:
One can throw an exception as follows:

throw new Error(reason);

or

throw {
name: exceptionName;
message: reason;
}

One can use a standard try … catch statement to catch Exceptions

try {
} catch (e) {
switch(e.name) {
case ‘Error’:

break;
default:
throw e;
}
}

There is only one catch clause as there are no Exception classes.

  • Error
  • EvalError
  • RangeError
  • SyntaxError
  • TypeError
  • URIError

With

With can be used to reduce the coding by indicating that we wish to work with attributes/functions of a specified object. But it does not work seamlessly and should be avoided.

with(o) {
foo = koda;
}

Which of the following is true:

o.foo = koda;
o.foo = o.koda;
foo = o.koda;
foo = koda;

What it actually does is this

if ('foo' in o) {
o.foo = 'koda' in o ? o.koda : koda;
} else {
foo = 'koda' in o ? o.koda : koda;
}

Which is logical but given the complexity of the logic, it is better avoided.

Introduction

This is the fourth post based on the book JavaScript – The Good Parts by Douglas Crockford. The previous post covered some features of functions in JavaScript. This post takes this forward and covers more features of functions in JavaScript. The key concepts are Closures and Inner Functions which are very powerful features available to programmers of JavaScript.

Closure and Inner Functions

The “inner functions” get access to all variables and parameters of the function they are defined within, with the exception of “this” and “arguments”. We saw example of this in the previous post.
Since a function is also a variable in JavaScript the values of the variables in a JavaScript function remains with the function for the lifetime of the function. A lifetime of the function depends on how the function is invoked. When a function is declared in the global scope and is invoked the lifetime of the function is limited to its execution time. Once the function is executed the function dies. When a function is used to create an object the lifetime extends to the lifetime of the variable. If this variable is at a global level then the lifetime of the function is equal to the lifetime of the document.
When a function is passed as a variable to another function, the lifetime of the function extends to the lifetime of the function that is being invoked. The function carries with it any values within it.
Consider a situation where we need to walk through all the nodes in the DOM of an HTML and invoke a function on the element. We need to recursively move through the elements and it is children and invoke the function on each of the element.

var WalkTheDOM = function (node, func) {
func(node); //Invoke the function with the node as the parameter
node = node.firstChild;
while (node) {
WalkTheDOM(node, func);
node = node.nextSibling;
}
};

Note that the right value of “node” is available to the inner function.
Let us now use this to identify all the elements with a specified “attribute” with a specified “value”.

var getElementsByAttribute = function (attr, value) {
var results [];
WalkTheDOM (document, function () {
var actual = node.nodeType === 1 && node.getAttribute(attr);
if (typeof actual === "string" && (actual === value || typeof value !== "string")) {
results.push(node);
}
});
}

Note how the variable “results” continues to be available to the function passed to WalkTheDOM. This is called closure.

Modules: Hiding State Value and Functions (Uses of Closure)

A typical way of implementing a counter would be to define a function as follows:

var Counter = function () {
var currentValue = 0;

increment = function (inc) { this.currentValue = this.currentValue + (typeof inc === “number” ? inc : 1); } decrement = function (dec) { this.currentValue = this.currentValue – (typeof dec === “number” ? dec : 1); } getValue = function() { return this.currentValue; } }

To create counters we could do the following

var counterA = new Counter();
var counterB = new Counter();
counterA.increment();
counterB.decrement();

But implementing in this fashion leaves the variable currentValue accessible from outside.
For example one could do

counterA.currentValue = 10;

Ideally the currentValue should be inaccessible from outside of the Counter object. This can be achieved by rewriting the Counter function as below.

var Counter = function () {
var currentValue = 0;
return {
increment: function (inc) {
this.currentValue = this.currentValue + (typeof inc === "number" ? inc : 1);
},
decrement: function (dec) {
this.currentValue = this.currentValue - (typeof dec === "number" ? dec : 1);
},
getValue = function () {
return this.currentValue;
}
};
}();

What is being done is that Counter function returns an object which contains the increment and decrement functions, but the outside world cannot access the currentValue variable. We can now instantiate counters as.

var counterA = new Counter();
var coutnerB = new Counter();
counterA.increment();
counterB.decrement();

And

counterA.currentValue will be invalid.

In a similar manner we can hand hide functions. Any function that is not returned as part of the object will be private to the global function and can be accessed from anywhere within that function.

Using setTimeout with Closure

Consider a use case where it is required to fade out a node slowly over a period of time. One will need to use the setTimeout function of JavaScript to slowly reduce the opaqueness of the node. But the problem that arises is how to keep the value of the node between two calls invoked by setTimeout. The easiest way out is to define a global variable which has this node and the setTimeout will function on this global variable. But what if one needs to fade out more than one node at a time? This can be solved elegantly by using closure as given below:

var fade = function (node) {
var level = 1;
var step = function () {
var hex = level.toString(16);
node.style.backgroundColor = "#FFFF" + hex + hex;
if (level < 15) {
level = level + 1;
setTimeout(step, 100);
}
}
}
fade ();
fade ();
fade();

The value of level and node is retained and carried forward from one call to another without the use of a global variable.

Cascade

Relook at the Counter function.

var Counter = function () {
var currentValue = 0;
return {
increment: function (inc) {
this.currentValue = this.currentValue + (typeof inc === "number" ? inc : 1);
},
decrement: function (dec) {
this.currentValue = this.currentValue – (typeof dec === "number" ? dec : 1);
},
getValue = function () {
return this.currentValue;
}
}
}();

To use the functions in this we need to do the following:

var counterA = new Counter();
counterA.increment(2);
counterA.getValue();

So if one needs to invoke two different functions one needs to put it in two different lines. Instead if we rewrite the function as

var Counter = function () {
var currentValue = 0;
return {
increment: function (inc) {
this.currentValue = this.currentValue + (typeof inc === "number" ? inc : 1);
return this;
},
decrement: function (dec) {
this.currentValue = this.currentValue - (typeof dec === "number" ? dec : 1);
return this;
},
getValue = function () {
return this.currentValue;
}
}
}();

We can now do this

counterA.increment().getValue();

This makes coding much easier and simpler. This is called cascading. Returning the object in methods that do not return anything else is called cascading.

Introduction

This is the third post in the series of posts based on the book JavaScript – The Good Parts by Douglas Crockford. The previous post covered details of how one can create and use functions in JavaScript. This post details out the features of functions in JavaScript. JavaScript functions have features which are not present in other languages and one needs to understand these details to write better JavaScripts and to understand the JavaScript written in the JavaScript libraries.

Arguments to a Function In addition to the explicit parameters passed to a function two more parameters are passed to a function.

  1. this: The value of this variable is discussed in detail below
  2. arguments: This is an Array like variable which has the list of arguments passed to the function

The value of “this” argument The value of the “this” argument passed to a function depends on how the function was invoked.
Invoking a function through “call” function of JavaScript
A method can be executed using the “call” of JavaScript.
When a global function is invoked
When a function defined in a global scope is invoked the value of “this” is the global object.
When Function is invoked as a method
When the function is defined inside another function it is called a method. When such a function is invoked the parent function is the value of “this”. All the attributes and function defined in the parent scope are accessible to this function through the “this” object.
If one has an inner function in a method then the “this” for this inner function will be the method. For the inner function to have access to the outer parent function of the method the method must expose it as its local variable. Typically this variable is called “that”
Example:

myObject.double = function () {
var that = this; //this is myObject
var helper = function () {
that
.value = add(that.value, that.value);
}
helper
();
}

“this” value in function “double” will be myObject.
“this” value in function “helper” will be “double”.
The function “helper” does not have direct access to myObject. It will have access to only the local variables of the function double. Unless double exposes the myObject through “that” helper method will not have access to myObject.
When function is invoked as a new
Although JavaScript provides prototype based inheritance it provides the classical way of instantiating an object using the “new” keyword. When a function is invoked using the “new” keyword the value of “this” will be the object that is created out of this invocation.
When function is invoked using the “apply” or “call” method
All functions can be invoked via apply or call method. The difference between apply and call is that apply takes an array for the list of arguments to the function being invoked and call takes individual arguments instead of an array.
Invoking using “call”

someFunction.call(thisArg[, arg1[, arg2[, ...]]]);

The thisArg1 is the object that will be passed as the value of “this” to the function someFunction
Invoking using “apply”

someFunction.apply(thisArg, [arguments]);

The thisArg1 is the object that will be passed as the value of “this” to the function someFunction
Example of using “call”

var Quo = function (string) {
this.status = string;
}
Quo.prototype.getStatus = function () {
return this.status;
}
var statusObject = {status: "A-OK"};
//statusObject does not inherit from Quo.prototype, but we can invoke getStatus and get the value
//of status as follows:
var status = Quo.prototype.getStatus.call(statusObject);
//the value of status will be "A-OK".

An example for apply will look the same, except that the arguments will be passed as an array.

The argument “arguments” In addition to “this” “arguments” is another variable that is available in each method. This is a list of arguments passed to the method. “arguments” is not an array in a true sense although it does behave array like. So functions that are normally available in array are not available with this variable.

Return from a function Every JavaScript function returns a value irrespective of whether there is a return statement or not. For functions that do not return anything this value is “undefined”.
The only exception is when a function is invoked with a “new” does not return anything. The “this”, the object created, is returned.
Pass by Reference All objects are always passed by reference. All primitive variables are passed by value.

Passing variables Passing variables is Pass by Value.

function myfunction(x){
// x is equal to 4
x
= 5;
// x is now equal to 5
}
var x = 4;
alert
(x); // x is equal to 4
myfunction
(x);
alert
(x); // x is still equal to 4


Passing Object Passing objects is pass by reference.

function myobject() {
this.value = 5;
}
var o = new myobject();
alert
(o.value); // o.value = 5
function objectchanger(fnc) {
fnc
.value = 6;
}
objectchanger
(o);
alert
(o.value); // o.value is now equal to 6

Passing functions Passing functions is a little more complicated. See the example below to understand how it functions, why it functions and how to actually achieve pass by reference.

function myobject() {
this.value = 5;
}
myobject
.prototype.add = function() {
this.value++;
}
var o = new myobject();
alert
(o.value); // o.value = 5
o
.add();
alert
(o.value); // o.value = 6
function objectchanger(fnc) {
fnc
(); // runs the function being passed in
}
objectchanger
(o.add);
alert
(o.value); // sorry, still just 6

Why does this happen? The problem here is the use of the “this” keyword. It”s a handy short-hand for referring to the current object context. When passing a function as a parameter, though, the context is lost. More accurately, “this” now refers to the context of the object making the call instead of the object’s function we just passed in. For standalone functions, this would be the window object and for functions called from an event, this would be the event object.
So how do we achieve this?
Option 1: When you know the method If you know the method of the object that will be called then it”s fairly easy. Just pass in the object instead of the function and call that instead. Using the objectchanger from the last example you”d get the following:

function objectchanger(obj) {
obj
.add(); // runs the method of the object being passed in
}
objectchanger
(o);
alert
(o.value); // the value is now 7

Option 2: When you don”t know the method If you don”t know the method of the object being passed in then you need to pass both the method and the object as parameters and use the call method. call is part of the JavaScript specification and allows a function to run in the context of another object. As a result, the this keyword will reference the right object: the object we passed in.
Here”s our objectchanger function one more time:

function objectchanger(fnc, obj) {
fnc
.call(obj); // runs the method of the object being passed in
}
objectchanger
(o.add, o);
alert
(o.value); // the value is now 7

Note the use of the method call.

Introduction

This is the second post based on the book JavaScript – The Good Parts by Douglas Crockford. In the first post we saw the basics of JavaScript with regards to variable, scope, type of variables etc. In that we saw that the type of a variable could be a Function or an Object. In this post we will see details of how Objects are defined and used in JavaScript

Functions in JavaScript

Before we get into Classes and Objects in JavaScripts it is important to understand some basics of functions in JavaScript
The power of functions in JavaScript is something that an Object Oriented Programmer never realizes. Functions are “First Class Citizens” of the language. They can be declared as variables, they can be passed across as parameters to other functions. These are features from a Functional Programming Paradigm and these give JavaScript a tremendous flexibility.
A function can be created using one of the following methods:

function foo () {
//do something
}

or

foo = function () {
//do something
}

or

var foo = function () {
//do something
}

or

Function.prototype.foo = function () {
//do something
}

Functions are by default created in the global scope and so can be invoked from anywhere.
Functions are treated as variables and can be passed around.

function foo () {
alert('a');
}
function bar (x) {
x(); //Invoking a function passed as a parameter.
alert('b');
}
bar(foo);

This is a principle that has been adopted from “Functional Programming” paradigm.

Objects in JavaScript?

An object is JavaScript is a container of properties which can be attributes or functions. It is a dictionary where each property can be accessed by their name. A property name can be any string including a blank string.
Note that there is nothing specific called a class. JavaScript has only objects.
Before getting into further details of Objects, let us first see how inheritance is possible in JavaScript. This is importance as it is quite different from what one would have seen and experienced in Object Oriented Programming.

Inheritance in JavaScript

One has two types of Inheritance in Software

  1. Classical: Like the types present in C++ and Java. In this one explicitly extends another object and gets the attributes and methods of the parent object.
  2. Prototype: This is the mechanism used by JavaScript to provide inheritance.

Inheritance by Prototype

In JavaScript every object and every function has a prototype. There is a global Object Prototype and a Global Function Prototype. These are the prototypes that are associated to an Object or a Function as the case may be, by default.
One can attach attributes and functions to the prototypes of the object. Once an attribute or a function is attached to the prototype of an object it is available to all instances of that object. For example if one wishes to introduce a trim function to the String object in JavaScript, one can achieve this as follows

if(!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g,'');
};
}

In line 1 we are checking if the function trim has already been defined in the prototype of the String object. If it has not been defined (note the usage of trim being “undefined” being treated as falsy) then define the trim function and assign it to the prototype of the String object.
The reason to check if the prototype already has a trim is to ensure that if in future JavaScript standards define the trim function in the String object prototype then one should use that implementation.
One can use the trim function on any string object.

function testTrim() {
var a = " abc ";
var b = a.trim(); //b should have a value "abc".
}

When an attempt is made to access an attribute in an object or when an attempt is made to execute a function of an object, the JavaScript runtime first looks for the same in the object; if found it uses this; if it is not found then it looks for the same in the prototype of the object; if found it uses this from the prototype; if not it looks for a prototype of the prototype and if found it looks for this in this prototype; this goes on till there are no more prototypes available.
It is in this manner that hierarchy is implemented in JavaScript.
It is possible to attach an object “x” as a prototype to another object “y”. By doing this the object inherits all the attributes and the functions and the prototype of the other object leading to inheritance. Note that inheritance in that JavaScript world becomes dynamic rather than the static inheritance that one sees in the Object Oriented world.
We can write a function “beget” as follows to attach one object as prototype of the other:

If (typeof Object.beget !== 'function')  {
Object.beget = function (o) {
var F = function() {};

F.prototype = o;
return new F();
};
} var another_stooge = Object.beget(stooge);

Note that we are attaching the function beget to the prototype of the “Global Object”, thus making it available to all objects.
In the above example the object “stooge” becomes the prototype of object “another_stooge” thus bestowing on “another_stooge” all properties of object “stooge” and its prototype.

Object and Function prototypes

JavaScript has two global level prototypes, one is the prototype for all Objects and another is for all Functions. The prototype of the Function.prototype is the Object.prototype. Any attribute or function attached to this becomes available to all the Functions or all the Objects respectively.

Creating Objects

Objects in JavaScript can be created using one of the following methods:

  1. new
  2. Object Literal
  3. Object.create

Using new

First create function which has the required attributes and functions.

function Person() {
this.name;
this.age;
this.isSeniorCitizen = function () {
return this.age > 60;
}
}
var johnDoe = new Person();
johnDoe.name = ‘John Doe’;
johnDoe.age = 50;

To use new to create an Object, first one needs to define a Function. Then one can instantiate an object which is represented by the Function. In the above example we have defined a function called Person. It can have two attributes “name” and “age”. It also has a function “isSeniorCitizen”.
To create an new instance of this object one can use the keyword new. This is the pattern that may Object Oriented Programmers will be familiar with. The other two mechanisms are something that is not encountered in the Object Oriented world.

Using Object Literals

One can create objects in JavaScript using simple Strings.

var johnDoe = {name: "John Doe", age: 50,
isSeniorCitizen: function () {return this.age > 60;}};

A similar syntax can be used to create an array using object. This is shown in the following example:

var listOfLifeStates = ["infant", "kid", "teenager", "adult", "middle age", "senior citizen"];

Note that it is possible define functions along with the attributes of the object, using object literals.
If this reminds one of JSON then one is not mistaken. JSON is a subset of Object Literals.

Using Object.create

JavaScript 5 introductions a new method called ‘create’ in the Object prototype. This allows instantiating objects which can inherit from other objects.

function Foo() {
this.name = "foo";
}
Foo.prototype.sayHello = function() {
alert("hello from " + this.name);
};
var myFoo = new Foo();
myFoo.sayHello();

If one wishes to create another object Bar which inherits from Foo we can do the following:

function Bar() {
}
Bar.prototype = new Foo();
Bar.prototype.sayGoodbye = function() {
alert("goodbye from " + this.name);
}
var myBar = new Bar();
myBar.sayHello();
myBar.sayGoodbye();

But the issue is that the property “prototype” is called also called “__proto__” in some environments. To avoid this confusion a new Object.create method has been introduced. This can be used as follows.

var Foo = {
name: "foo",

sayHello: function() { alert(“hello from ” + this.name); } }; Foo.sayHello();
Now use Object.create to create bar with a prototype of Foo.

var bar = Object.create(Foo, { sayGoodbye:  function() {alert("goodbye from " + this.name); }});
bar.sayHello();
bar.sayGoodbye();

This is much cleaner than using the prototype directly.
But some environments still do not have the implementation of Object.create. To overcome this problem one can define one’s own create function in the Global Object prototype as below:

if(typeof Object.create !== "function") {
Object.create = function (o, props) {
function F() {}
F.prototype = o;
extend(F, prop);
return new F();
function extend(obj, props) {
for(prop in props) {
if(props.hasOwnProperty(prop)) {
obj[prop] = props[prop];
}
}
}
};
}

Now one can use Object.create fearlessly irrespective of the environment in which one’s scripts run.

Adding functions to prototypes

The normal way to add a function to a prototype is as

Object.prototype. = function () {
}

To make this simpler we can add a method called “method” to the global function prototype as follows:

Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
}

Now one need not be worried about prototype. To add a method to a function all one needs to do is as described in the following example.
To add a method to the Number object to convert numbers to integer we can do the following:

Number.method ('integer', function () {
return Math[this < 0 ? 'ceiling': 'floor'](this);
});

Note the ability to select the function to execute using the ternary operator
To add a trim method to all Strings

String.method('trim', function() {
return this.replace(/^s+|s+$g, '');
}

To avoid clashes with other libraries we should set the function if and only if it does not exist. So change the ‘method’ function as follows:

Function.prototype.method = function (name, func) {
if (!this.prototype[name]) {

this.prototype[name] = func; } return this; }
This will ensure that the method will be created in the object only if one does not already exist. Note the use of [] to access the attribute/function in an object. Not only can one use the dot notation to access the function or the attribute but one can also use [] to access the function or attribute.

Attributes in an Object and hasOwnProperty

To go through the attributes in a JavaScript object the following loop can be used.

for (myvar in object) {
if (obj.hasOwnProperty(myvar) {
alert("Value of attribute " + myvar + " in object is " + obj[myvar]);
}
}

The method hasOwnProperty indicates if the attribute or function belongs to the object or if it is has been inherited through the prototype. The above method will display only those attributes which are attached to the object directly. It will not display the methods it has inheried through its prototype. If one removes the hasOwnProperty function then one will get a list of all the attributes and functions included in the prototype hierarchy of the object.

Delete operator

JavaScript has a delete method using which one can delete methods and attributes in a JavaScript object.

Person = function (pName, pAge, pOccupation) {
this.name = pName;

this.age = pAge; this.occupation = pOccupation; } var johnDoe = new Person(“John Doe”, 35, “vagabond”); //This will delete the attribute occupation from object johnDoe. delete johnDoe.occupation;
Note that the function delete will only delete attributes and functions directly associated with the object and not the ones in the prototype hierarchy.

Instanceof in JavaScript

The method “instanceOf” can be used to check the type of object. This walks up the prototype and checks with all the prototypes in the hierarchy. If one wishes to restrict avoid the prototype hierarchy then we should check object.constructor === “”. Care needs to be taken to ensure that the object is not null if one wishes to check with constructor.
instanceOf does not work with objects instantiated across windows. E.g. between the parent window and the IFrame or parent window and window opened.
Note that Array is a special object that has certain specific properties like length. But an Array is not really an Array (as in other languages), but it is an object where the names of the properties are numbers. These numbers cannot be negative and the length of the Array is equal to the highest number + 1 and not equal the number of elements in the Array.

Introduction

JavaScript was and is still a much maligned language although it is gaining popularity. It is still dismissed as a language useful only to validate inputs in the browser. The fact is that JavaScript is a very powerful language and has features that far exceed the ones available in a traditional Object Oriented Programming Language is thus far known and appreciated only by a minority.
The name “JavaScript” gives a strong connotation that it is a lesser sibling or a subset of Java. But nothing could be further from truth.
This is the first part in the series of posts based on the book JavaScript – The Good Parts by Douglas Crockford.
BTW: This book is a must read for anybody working with JavaScript.
In this post we will cover a few basic topics in JavaScript.

Variables in JavaScript

Some facts about the variables in JavaScript

  • All variables in JavaScript are by default Global. This means any undeclared variable is a Global variable.
  • Variables declared inside a function are local to the function.

Checking Type of Variable – typeof operator

Since JavaScript is not a static typed language there is a mechanism to determine the Type of a variable at any point in time.
typeof will return one of the following values:

  1. number
  2. string
  3. boolean
  4. undefined: This indicates that no value has been assigned to the variable. This is different from null
  5. function: Note that a variable can be a function. This is possibly one of the biggest advantages of Java over the Object Oriented Languages. It is also the least understood feature given the obsession with Classes and Objects of the Object Oriented Programmers. We will see more details and power of this feature in later posts.
  6. object: Note that we can have objects in JavaScripts, making it no lesser than any other Object Oriented Languages.

Truthy and Falsy values in JavaScript

It is necessary to understand what values evaluate to a “false” and what values evaluate to “true“. This is important to understand as many of the libraries that have been written in JavaScript exploit these features and without this one can get lost.
The following values are considered Falsy in JavaScript

  1. Boolean value false
  2. Object value undefined
  3. Number value 0
  4. Object value null
  5. The empty string “”
  6. The Number NaN (Not a Number)

Everything else is truthy value.
Important notes
The boolean value of a string containing the text “false” is true.
A string value “0” is true while a number value 0 is false.

The || operator

Although the || operator is used for Boolean “OR” operations it actually returns the value of the first operant which is truthy. So in essence it is not really an OR operator in the traditional sense, in that it does not return a boolean “true” or a “false”, rather it returns the first value in the statement which evaluates to “true”.
It is returns the last value if none of them evaluates to “true”.
See the example given below:

var a;
var b = 0;
var c = false;
var d = {};
var e = 1;
var f = a || b || c || d || e;
f will be equal to d.

The && operator

Although the && operator is used for Boolean “AND” operations it returns the value of the last operant which is truthy.

var a;
var b = 0;
var c = false;
var d = {};
var e = 1;
var f = a && b && c && d && e;
var g = d && e;
f will be equal to "undefined" obtained from "a".
g will be equal to "e".

This can be used to do something as follows:

var a = node && node.name; 

instead of a verbose code like this.

var a; 
if (node) {
a = node.name;
}

In the next post we will look at Objects in JavaScript and the associated features. Till then enjoy coding in a typeless language and if you do not wish to wait for the posts then pick up the book or listen to the topics covered in the book from horses mouth (Douglas Crockford)


Categories