◄►
Home

JavaScript 1.5 by Example


There is much quirky behaviour within JavaScript, which is difficult for the newcomer to search for, or even stumble apon. This article attempts to present many of these quirks in as concise a way as possible.

Variables

var a = '010', b = '2.1';

a + b;
"0102.1"

// parseFloat(a) + parseFloat(b)
+a + +b
12.1

// Math.floor(a) + Math.floor(b)
~~a + ~~b
12

// octal syntax throws an error in strict mode
parseInt(a) + parseInt(b)
10

// 2nd argument ensures a base 10 result
parseInt(a,10) + parseInt(b,10)
12

// 10..toString() + (2.1)['toString']()
'' + 10 + 2.1
"102.1"
Other types:
var myUndef = undefined, myNull = null,
	myBool = true || false, now = new Date;

Regular Expressions

The single-line "s" modifier is missing in standard JS. Use /[^]/ or /[\s\S]/ instead of /./
var R_domain = /^[a-z0-9-]+(\.[a-z0-9-]+)+$/i,
	R_constructed = new RegExp('^\\w+$','g'),
	url = 'my.domain.org.uk',
	parts, country,
	isDomain = R_domain.test(url),
	myLi = R_domain.lastIndex;
	
if( (parts = R_domain.exec(url)) ){
	var fullMatch = parts[0],    // all matched
		country = parts.pop();     // ".uk"
}
url.replace(/\.(\w)/g, '-'+('$1').toUpperCase());
"my-domain-org-uk"

url.replace(/\.(\w)/g, function(re){
	return '-'+re[1].toUpperCase()
} );
"my-Domain-Org-Uk"

Objects (Hashes) and Arrays

// var myArray = Array(2);
var myArray = [,,];

// var localObject = new Object;
var localObject = {};

window.globalObject = {};

// fill up object as it is declared
var human = {
	body: {
		eye: [
		  left: { colour: 'blue' }
		]
	}
};
human.body.eye.push( { right:{} } );
human['body']['eye']['right'].colour = 'hazel'; // other notation
delete human['body'].eye;                       // we are blind!

Loops and Brackets

var key, val, msg = '';

for( key in myObject ){
	msg += 'Brackets enable multiple statements inside loop. ';
	val = myObject[key];
}

for( key in myObject )
	msg += 'Commas enable multiple assignments without brackets. ',
	val = myObject[key];

Functions

function speed( u, t, a ){
	return u * arguments[1] + ( .5 * a * Math.pow( t, 2 ) )
}
speed( 4, 10, 9.8 );
530
Other ways of calling functions:
var scope=this;
speed.apply( scope, [4, 10, 9.8] );
speed.call( scope, 4, 10, 9.8 );
The best way of emulating eval is like so:
window.Fun=function(f){
	return Function('a','b','c',f)
};
var speedy = Fun("return a * b + ( .5 * c * Math.pow( b, 2 ) )");
speedy( 4, 10, 9.8 );
530
A function defined inside another function has access to the outer's variables.
var outy = function(a){
	var inny = function(b){
		return a+' '+b*3;
	};
	return inny(a*2);
};
outy(2);
2 12

Classes

Start with a constructor function, then use prototype, a special property object for classes
function Lifeform( object ){
	this.init( object )
}
Lifeform.prototype = {
	init: function( object ){
		for( var i in object )
			this[i] = object[i]
	}
};

function Person( object ){
	Lifeform.call( this, object );
	this.genus = 'Human';
}
Person.prototype = new Lifeform;

var john = new Person({
	name: 'John',
	family: 'Connor'
});
Existing objects can be enhanced after their creation
Person.prototype.fullName = function(){
	return this.name + ' ' + this.family
};

(function(){
	return this.fullName() +', '+ this.genus;
}).apply(john);
"John Connor, Human"
We can enhance built-in JavaScript objects
String.prototype.reverse = function(){
	return this.split('').reverse('').join('')
}

'Race fast, safe car.'.reverse();
".rac efas ,tsaf ecaR"

Scope

The following line should be the first in your code. Note that it bans octal, with, arguments.caller and arguments.callee
"use strict";
The only way to create (my) private variables is inside function closures:
a=1; (function(){a=2}()); a;
2

a=1; (function(){var a=2}()); a;
1
Be careful with this - like Perl's $_, its scope changes!
var full=john.fullName; full();
" undefined"

john.fullName();
"John Connor"