This Is Not The JavaScript Our Parents Would Know
In the bad old days JavaScript was not compatible across browsers. JavaScript development was painful, frustrating and costly. More recently JavaScript has become the poster-child for effective web programing and the next wave of Web 2.0 applications. Why is this so? I investigate this quandary in the following essay.
Lets start by looking at the brief history of JavaScript which turned 10 years old last month.
History
1995 – JavaScript 1.0 / aka “LiveScript” Early ECMAscript + DOM level 0 without images / Netscape2,IE2
1996 – JavaScript 1.1 / (JScript1.0) Early ECMAscript + DOM level 0 / Netscape 3, IE3
1997 – JavaScript 1.2 / (JScript2.0) ECMAscript + DOM level 0 + layers or proprietary DOM / Netscape 4, IE4
1998 – JavaScript 1.3 / (JScript3.0) ECMA-262 DOM level 0 + layers or proprietary DOM / Netscape 4.05-4.76*, IE4
1998 – JavaScript 1.4 / (only by Netscape’s server side JavaScript)
1999 – JavaScript 1.5 / (JScript5.6) ECMA-262 Edition 3 + DOM level 0 + W3C DOM / Netscape 6, IE5,IE6
200? – JavaScript 2.0 / ECMA-262 Edition 4 /
Compatibility
Different versions and indicates where IE and Navigator versions of JavaScript are roughly compatible:
Browser |
NN3.0 |
NN4.0 – 4.05 |
NN4.06 – 4.76 |
NN6.0+ |
IE3.0 |
JavaScript 1.1 JScript 1.0 |
|||
IE4.0 |
JavaScript 1.2 JScript 3.0 |
JavaScript 1.3 JScript 3.0 |
||
IE 5.0 |
JavaScript 1.5 JScript 5.0 |
|||
IE 5.5 |
JavaScript 1.5 JScript 5.5 |
|||
IE6.0 |
JavaScript 1.5 JScript 5.6 |
The table only gives a very rough approximation, and in those terms JavaScript IE3 = NN3, IE4 = NN4 and IE5+ = NN6. An example of the small differences is the try..catch clause, which is supported in JavaScript by IE5+ and NN6+, but not in IE4 or NN4. Source
What Happened To Netscape 5?
Netscape 5.0 was based on the 4.x code base that Netscape released in 1998. Netscape also released the beginnings of Netscape Gecko — a new code base — at about the same time. Soon the Web was clamoring for Gecko’s superior performance and standards support. So, [in 1999], Netscape switched code bases and rewrote the new software based on Gecko, canceling 5.0 (Mozilla classic) in favour of Netscape 6.
Why Is JavaScript So Damn Usable Now?
The answer is features, persistence and hype.
People have been working hard to make JavaScript work. JavaScript is the one true common platform. It is in every modern browser. With the correct arrangement of certain features, the kinds of problems that used to make people want to take a stiff drink at the mention of JavaScript of Dynamic HTML have gone away. Because of the hype of Web 2.0, mostly driven by the success of Google, blogger and flickr – JavaScript is very very hot at the moment.
Freeze The Clock at 1998
The developer community has essentially drawn a line under JavaScript1.3 and is using the JavaScript syntax and features of 1.3 and scaling up to the DOM/CSS and library support given the executing browser. (But that is a topic unto its own)
With the currently available libraries, It is possible with reasonable effort to create JavaScript that will run predictably on the following browsers.
Opera 7+ , Safari 1.3 , Mozilla/Firefox 1.0.X , Explorer 5.2 on Mac OS X , Explorer 5+ on Windows
Classes
To help in code re-use and to create code with a better structure, a heavy use of Object Orientated JavaScript has been under way for the last 4 years. Constructors, Typing, Namespaces Inheritance and Polymorphism. This has promoted code re-usability, to the point that the JSAN project has been able to take off and provide a library of JavaScript classes and a standard by which libraries can be easily installed and at run-time dynamical loaded and imported. See line 00118 of this file.
function Cat(p_name)
{
this.m_name = p_name;
this.talk = function()
{
alert( this.m_name + " say meeow!" )
}
}l_cat1 = new Cat("Felix");
l_cat1.talk(); //alerts "Felix says meeow!"l_cat2 = new Cat("Ginger")
l_cat2.talk(); //alerts "Ginger says meeow!"
.Prototype Object Member
Introduced with JavaScript 1.1 and is not to be confused with, but is the reason that the excellent prototype JavaScript library has that name.
In JavaScript, you’re allowed to add custom properties to both prebuilt and custom objects. Here’s an example of each:
//Adding a custom property to a prebuilt object - can't do this to all prebuilt objects! var l_image=new Image(); l_image.size="26k; //Adding a custom property to a custom object function Circle(p_radius) { this.m_radius = p_radius; } function Area() { return this.m_pi*this.m_radius*this.m_radius } var l_smallcircle = new Circle(2.0 l_smallcircle.m_pi = 3.14159; l_smallcircle.area = Area; var l_bigcircle = new Circle(20.0);
A custom property added this way only exists for that instance of the object. If I were to instantiate another instance of Circle(), called “l_bigcircle”, for example, l_bigcircle.m_pi would by default return “undefined” and the area function would not be one one its members until I go over the process again of first defining m_pi and area, as with l_smallcircle.
There are times when you’ll want to add a custom property that’s only reflected on a particular instance of an object, and other times, when you require all instances of the object to have the custom property.
The prototype object is here to help when you wish to quickly add a custom property to an object that is reflected on all instances of it.
Circle.prototype.m_pi = 3.14159;
All instances of Circle() now has the m_pi property prebuilt into them.
Circle.prototype.area = Area;
var l_smallcircle = new Circle(2.0);
var l_bigcircle = new Circle(20.0);
Now, all instances of the circle object contain an area() method!
Apply/Call
JavaScript1.3 defines two new methods. apply() and call(). These can be used to manipulate the ‘this’ reference in JavaScript which means that you can in effect emulate object method composition.
You can project any given object and make it ‘this’ within a function call.
These features make it easy to re-use code and stitch functions and objects together into a classical Object Orientated structure.
Arguments
You can refer to a function’s arguments within the function by using the arguments array. This array contains an entry for each argument passed to the function.
The arguments array is available only within a function body. Attempting to access the arguments array outside a function declaration results in an error.
You can use the arguments array if you call a function with more arguments than it is formally declared to accept. This technique is useful for functions that can be passed a variable number of arguments. You can use arguments.length to determine the number of arguments passed to the function, and then process each argument by using the arguments array. (To determine the number of arguments declared when a function was defined, use the Function.length property.)
Example.
function listItems()
{
var items = listItems.arguments.length
document.write("<UL>\n")
for (i = 0;i < items;i++)
{
document.write("<LI>" + listItems.arguments[i] + "\n")
}
document.write("</UL>\n")
}
The function may be called as follows:
listItems("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Happyday");
Try/Catch/Finally
Added as part of JavaScript 1.4 (So Beware) – Server Side JavaScript
Used to catch any errors, as soon as the error event occurs, the program switched flow to the catch statement with an exception object that describes the error.
No more JavaScript Error Alerts.
With try/catch you can aggressively test for browser features that may cause an error, but you can test for try and catch. 🙂
try
{
var i = 0
if(i != 1)
{
throw "ThrowError"
}
}
catch(e)
{
if(e == "ThrowError")
{
document.write("This is a thrown error message: i is not one.<br/>")
}
}
finally
{
document.write("This is the finally message.")
}
One of my future tests will work out the cost of try/catch
Namespacing
Taking two or more random scripts and putting them on one page can often result in clashes and confusing behaviour as each script interferes with the other variables and functions simply because one scripts variable names and/or function names happen to be the same as another script.
To solve this the current trend is for every script developer to create a namespace.
In JavaScript a namespace is a normal JavaScript with a name that contains all the methods and variables for a given related set of code.
Object Literals are neater then the original old school, method of declaring the object to be used as a namespace.
var MyNamespace =
{
check_my_box :
function(element_name)
{
var my_element = document.getElementById(element_name);
my_element.checked = true;
}
,
uncheck_my_box :
function(element_name)
{
var my_element = document.getElementById(element_name);
my_element.checked = false;
}};
MyNamespace.check_my_box("mycheckbox");
Because a namespace is simply an named object, its existence can be tested for. This allows all sorts of wonderful probing for required namespaces and makes it possible to guard against multiply including the same namespace multiple times.
There is a 3% performance hit on function calls for each level of the namespace.
Web 2.0 Hype
Web 2.0 is a term often applied to a perceived ongoing transition of the World Wide Web from a collection of websites to a full-fledged computing platform serving web applications to end users. The proponents of this thinking expect that ultimately Web 2.0 services will replace desktop computing applications for many purposes.
DoubleClick was Web 1.0; Google AdSense is Web 2.0.
Ofoto is Web 1.0; Flickr is Web 2.0.
O’Reilly Media, Battelle, and MediaLive launched the first Web 2.0 Conference in October 2004. The second annual conference will be held in October 2005.
Web 2.0 is intimately linked to the new buzzword SOA, Services Oriented Architectures, the poster-child for this is the Salesforce product. http://www.salesforce.com
At a deeper psychological level, the term “Web 2.0” has attracted much wishful positive thinking, possibly because the term infers that the great gravy-train of Web 1.0 could return. Calmer minds who remember the train-wreck are concentrating on the meat of the movement, which is is the emergence of JavaScript as the long promised “write once deploy anywhere” platform, AJAX and the emergence of SOA (Services Oriented Architectures).
AJAX
First described in this blog post and most recently in this post.
WTF? We have been doing this with flash for years? Hell we have been doing this in our own applications for years as well (See Demonstrations Below), what gives?.
Lots of AJAX is hype. Buts a good Meme and it serves as a rallying point for a the HTML developer community to catch up and start doing applications properly.
Ajax or Asynchronous JavaScript and XML is a term describing a web development technique for creating interactive web applications using a combination of:
- HTML (or XHTML) and CSS for presenting information
- The Document Object Model manipulated through JavaScript to dynamically display and interact with the information presented
- The XMLHttpRequest object to exchange data asynchronously with the web server. (XML is commonly used, although any text format will work, including preformatted HTML, plain text, and JSON)
AJAX suffers from the same problems as Macromedia Flash – bookmarking and tracking. http://alexbosworth.backpackit.com/pub/67688
And With These Features You Can?
Develop!
- ..readable and maintainable code.
- ..testable code. With a class structure unit tests can be easily built into the libraries.
- ..applications that make less round trips to the server.
- ..applications in which the behavior, style and content are cleanly separated. (See The MetaWrap WireWrap library)
The Need For Speed
JavaScript engines are highly optimised and very efficient, but still very slow compared to C or Java. “JavaScript is about 5,000 times slower than C, 100 times slower than interpreted Java, and 10 times slower than Perl”
Given Moore’s law – “Computing power doubles every 18 to 24 months”, JavaScript is now as fast as interpreted Java was in 1998 and as fast as C was in 1993. And there were some decent Java applications in 1998.
JavaScript is actually faster, because it is highly granular.
Many modern JavaScript interpreters feature just-in-time compilers that can run code very efficiently.
Google got Google Maps working on Safari, by creating an entire Xpath, XSLT and DOM library in JavaScript which runs well because of a good algorithm and effective use of regular expresions.
The Future – JavaScript 2.0
http://www.mozilla.org/js/language/js20/
http://www.mozilla.org/js/language/es4/index.html
Best Practice For Cross Browser Development
Read this site. All of it.
Never Use Browser Detection – use Feature detection.
Demonstrations
2001 – MetaWrap JavaScript Library
2002 – Liberate VOD
2003 – V8 Media Center Edition
2004 – V8 Broadband Schema Editor
2005 –
JsUnit – Simple JavaScript Unit Testing System
Macro – Simple Macro Recorder and Playback
Page – Example Event Manipulation
Wirewrap – How to cleanly separate Behavior Style and Content using.
XSLT – Driven Page rendering
Testing
http://www.edwardh.com/jsunit/
http://mir.aculo.us/articles/2005/08/03/more-automatic-testing-with-javascript
http://www.hanselman.com/blog/IntroducingWatirMakerRecordingForRubybasedWatir.aspx
Libraries Worth Looking At
There are so many, but here is an interesting example of a series of libraries, each relying on the previous.
http://www.openjsan.org/doc/c/cw/cwest/JSAN/0.10/lib/JSAN.html
http://openrico.org/rico/demos.page