Introduction
In this article, I would like to share some of the interesting things I came to know about JavaScript.
These are the five tips we will see:
- Dynamic script loading
- Instantiation without "
new
" - Memoizing
- Mixin classes
- Inheritance by cloning
#1 Dynamic script loading
Most of the time, we load all the scripts and other resources initially when the page renders. Loading all scripts initially increases HTTP requests to the server and considerably reduces the time taken to see the page by the user.
As an example, when working with Google Maps, usually we load the Google Maps API initially and show the map. What will be the case if you want to show the map only when the user needs it? Here is the script that does that job!
var api = "http://maps.google.com/maps/api/js?sensor=false&callback=initialize";
function loadScript(src) {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = src;
document.body.appendChild(script);
}
function initialize() {
var myLatlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 8,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
<div id="map_canvas" style="width:500px; height:500px"></div>
<input type="button" value="Load Map" onclick="loadScript(api)" />
#2 Instantiation without "new"
Instantiating classes is normally done by the new
operator in most languages including JavaScript. Below is the typical way of instantiating a class in JavaScript:
function Book(isbn, author, title)
{
this.isbn = isbn;
this.author = author;
this.title = title;
};
Book.prototype = {
getIsbn: function(){
return this.isbn;
},
getAuthor: function(){
return this.author;
},
getTitle: function(){
return this.title;
},
};
var book1 = new Book("1590597273", "John Resig", "Pro JavaScript Techniques");
By modifying the above code, we can instantiate the Book
class like calling a method:
var book1 = Book("1590597273", "John Resig", "Pro JavaScript Techniques");
Here is the code:
function Book(isbn, author, title)
{
if(window == this)
return new Book(isbn, author, title);
this.isbn = isbn;
this.author = author;
this.title = title;
};
#3 Memoizing
Memoizing is a technique for optimizing methods. If a method does complex processing that doesn't need to be done repeatedly, we can use this technique to change its implementation dynamically.
One of the best places we can use this concept is in creating a XmlHttpRequest
object. Since the object that is needed for AJAX communication differs from browser to browser and even in different versions of IE, every time we have to sniff the browser before creating the object.
By memoizing, we can avoid the browser detection every time we create the XHR object.
createXhrObject: function() {
var methods = [
function() { return new XMLHttpRequest(); },
function() { return new ActiveXObject('Msxml2.XMLHTTP'); },
function() { return new ActiveXObject('Microsoft.XMLHTTP'); }
];
for(var i = 0, len = methods.length; i < len; i++) {
try {
methods[i]();
}
catch(e) {
continue;
}
this.createXhrObject = methods[i];
return methods[i];
}
throw new Error('SimpleHandler: Could not create an XHR object.');
}
};
In the above method createXhrObject
, we are storing different methods that instantiate different objects for AJAX communication in an array. Then, we iterate through the array, finding the right method and overwriting it to the createXhrObject
.
#4 Mixin classes
Inheritance is one of the nice ways for code reuse. Sometimes it won't help! For example, when you want to use methods of another class that are totally different, we can't inherit from it. In the example below, we have two classes Mixin
and Book
.
var Mixin = function() {};
Mixin.prototype = {
serialize: function() {
var output = [];
for(key in this) {
output.push(key + ': ' + this[key]);
}
return output.join(', ');
}
};
var Book = function(isbn, author, title)
{
this.isbn = isbn;
this.author = author;
this.title = title;
};
Book.prototype = {
getIsbn: function(){
return this.isbn;
},
getAuthor: function(){
return this.author;
},
getTitle: function(){
return this.title;
},
};
The Mixin
class has a method serialize
that serializes any object into a JSON string. We would like to use the serialize
method in the Book
class. Since the two classes are entirely different, we can't inherit Book
from Mixin
. Don't worry! We have a nice way to do this.
function augment(receivingClass, givingClass) {
for(methodName in givingClass.prototype) {
if(!receivingClass.prototype[methodName]) {
receivingClass.prototype[methodName] =
givingClass.prototype[methodName];
}
}
}
In the above function, we are copying all the methods of the Mixin
class to the Book
class. By using this technique, we can dynamically copy methods of one class to the other that are entirely different.
#5 Cloning
In all the languages I have seen, to create objects, first we write a class that acts as a blue-print, then we instantiate it. In the real world, there are no classes, only objects everywhere! But in JavaScript, we can do something that we can't imagine in other languages. One example is we can directly create objects.
Below is a JavaScript object created directly without a class:
var Tooltip = {
showTip: function(el, text){
},
hideTip: function(){
}
}
This explores a new way of inheritance called Prototypal Inheritance or simply Cloning. Here, first we create an object, then we clone it to create new objects that have the same or more behaviors. The most important thing in cloning is the clone
function itself that clones any object to create another object.
Shown below is the clone
function:
function clone(object) {
function F() {}
F.prototype = object;
return new F;
}
If you want to create a clone of the above Tooltip
object, call clone(Tooltip)
.
If you enjoyed the tips, don't forget to give your comments and vote :)
**JavaScript is awesome**