JavaScript has two interesting features: higher-order functions and prototypial inheritance. If you understand these two and you know at least one other curly-brace language, you basically understand JavaScript. Because you're in a hurry, the following explanation of these two concepts is extremely condensed. Read everything carefully and you'll be a JavaScript expert faster than you can say "Antidisestablishmentarianism".
Higher-order functions
In JavaScript, everything is an object (that is a lie, but for the sake of this article let's pretend that it's true). Functions are objects, too. You can assign functions to variables, you can have functions return other functions and you can have functions accept other functions as parameters.
Click anywhere in the code to remove line numbers.
1 var f = function(a) {
2 return function() {
3 alert(a());
4 };
5 };
6 f(function() { return "Hello World"; })(); Let's see if we can figure out what this code does: The variable f is assigned an anonymous function (anonymous, because it doesn't have a name) which has one formal parameter a. The function now assigned to f returns itself a function which, when called, calls another function a and displays its return value in a message box. The function a that the inner function invokes is actually the formal parameter a of the outer function now assigned to f. The inner function can access the outer function's formal parameters (and local variables), because JavaScript supports a concept known as closures. When a function accesses variables defined outside of its local scope (but within the scope chain, that is within one of the enclosing scopes), the function captures these variables (the variables themselves, not their values) and preserves them, even beyond the lifespan of the scope they were originally defined in. So now f refers to a function that accepts a parameter a and that returns a function which invokes a and displays its return value. On the next line, we call f and pass to it a function that returns the string "Hello World". Since f itself returns a function, we have to call whatever is returned by f so the message "Hello World" will be displayed on screen.
Prototypial inheritance
In JavaScript, objects are dictionaries with some additional magic. Here, let me show you:
Click anywhere in the code to remove line numbers.
1 var o = new Object();
2 o.k = 100;
3 alert(o.k); Here we create a new object, assign the value "100" to a new key k then read the value back from the object (or dictionary) and display it in a message window. No magic so far.
Click anywhere in the code to remove line numbers.
1 function Vehicle(wheels) {
2 this.wheels = wheels;
3 }
4 var a = new Vehicle(2);
5 var b = new Vehicle(4);
6 alert(a.wheels);
7 alert(b.wheels); This piece of code is a little more interesting: here we create two objects a and b using the new operator on a function called Vehicle. The new operator creates a new, empty object (or dictionary), calls the function it is used on and implicitly passes to it the new empty object through the pseudo-variable this. So it basically does the following (not legal JavaScript):
Click anywhere in the code to remove line numbers.
1 function Vehicle(this, wheels) {
2 this.wheels = wheels;
3 }
4 var a = Vehicle(new Object(), 2); If you manually inline-expand the code above, you get the following:
Click anywhere in the code to remove line numbers.
1 var a = new Object();
2 a.wheels = 2; Compare this to the first example in this section and you'll find that they're identical. Now take a look at this:
Click anywhere in the code to remove line numbers.
1 function Car() {
2 this.honk = function() {
3 alert("Honk! Honk");
4 };
5 }
6 Car.prototype = new Vehicle(4);
7 var c = new Car();
8 c.honk();
9 alert(c.wheels); Car is another function that is used along with the new operator to initialize objects. In this particular case, a new key honk is created and an anonymous function is assigned to it. This is one way of creating methods (it has some issues, but those are beyond the scope of this article). Now the next line is interesting: a new Vehicle-object is created and assigned to a key prototype on the Car function. Keep this in mind as you go over the next three lines. A new Car object is created, the method honk is invoked and the value of the key wheels is displayed on screen. But where does this key wheels come from? Enter prototypes. When the JavaScript runtime looks up an object member (a key), it performs two steps: it inspects the object itself and if the object does not contain such a key, it inspects the object's prototype chain. Whenever an object is created using the new operator, the object is secretly given a magic attribute __proto__ which refers to the prototype attribute of its constructing function (in this case, the Car function). The prototype is nothing more than another object which itself has a __proto__ attribute thus creating a chain of linked objects. Because of the way JavaScript looks up object members, an object essentially inherits all of it's prototype's attributes. With this knowledge, you can do some really wacky things:
Click anywhere in the code to remove line numbers.
1 Car.prototype.explode = function() {
2 alert("Bang!");
3 };
4 c.explode(); That's right, you can retroactively add new attributes and methods to existing objects by messing with the prototype of its constructing function and the best thing: this also works with built-in types.
Putting it all together
Alright, now that you've jumped into the deep end of JavaScript, let's put everything together into a slightly larger example:
Click anywhere in the code to remove line numbers.
1 function Vehicle(wheels) {
2 this.wheels = wheels;
3 }
4
5 var Motorcycle = (function() {
6 var numMotorcycles = 0;
7
8 var constructor = function(color) {
9 ++numMotorcycles;
10
11 this.keyInTheIgnition = false;
12
13 this.getColor = function() {
14 return color;
15 };
16 };
17
18 constructor.getMotorcycleCount = function() {
19 return numMotorcycles;
20 };
21
22 constructor.prototype = new Vehicle(2);
23 constructor.prototype.accelerate = function() {
24 if (this.keyInTheIgnition) {
25 alert("Vroom!");
26 }
27 };
28
29 return constructor;
30 })();
31
32 var motorCycle = new Motorcycle();
33 alert(Motorcycle.getMotorcycleCount()); This may seem weird at first, but all it really does is use concepts from the earlier examples in slightly more interesting ways. If you can figure out what this code does, you're ready for the next step (whatever that is). If you can't figure out what this does, feel free to ask questions in the comments.
Also note that while higher-order functions and prototypial inheritance are not significantly more complicated than explained here, there are some corner cases that you should consider, most of which have been shamelessly ignored by this article for the sake of brevity.
Confused? Check out JavaScript for people who are in slightly less of a hurry for more JavaScript goodness.

18 comments
Write a new comment | Trackback URI for this entryIt was fun trying out your examples in the developer tools of Google Chrome.
function MotorCycle {..} Motorcycle.prototype = new Vehicle(2); and Motorcycle.prototype.accelerate = function () {...}@Sahid Khan: Excellent question. In this specific example, you could do it either way and it wouldn't actually make a difference. What creating and invoking the anonymous function does is, it creates a new scope which can be used to do intesting things like emulate static member variables and -functions. Check out this article for a more concrete example: http://kaijaeger.com/a...ern-in-javascript.html. In the last example of this article, the "on-demand scope" trick is not actually necessary though. It might have been a little late when I wrote that ;-) I'll fix it in a second though.
constructor.getMotorcycleCount = function() { return numMotorcycles; }I thought you might like to know some of the reasons why you are not getting enough Social Media and Organic search engine traffic for Kaijaeger.com
1. Social profile is not available in top Social media websites.
2. Your site has 5 Google back links, this can be improved further.
There are many additional improvements that could be made to your website, and if you would like to learn about them, and are curious to know what our working together would involve, then I would be glad to provide you with a detailed analysis in the form of a WEBSITE AUDIT REPORT for FREE.
Our clients consistently tell us that their customers find them because they are at the top of the Google search rankings. Being at the top left of Google (#1- #3 organic positions) is the best thing you can do for your company's website traffic and online reputation.
Sounds interesting? Feel free to email us or alternatively you can provide me with your phone number and the best time to call you.
------------------------- ------------------------------ ----------
Best Regards,
Maria Wilson
SEO Consultant
(347) 329-2976
---------------------- ------------------------------ --------------
PS1: This is onetime email and you may ask us to “REMOVE” you from our mailing list.
PS2: I found your site from online advertising but did not click.
PS3: We operate 24 x7. I will be happy to send you links to price list, money back guarantee, client rankings, client testimonials, “How we are different from others?”, and “Why should you choose us?” on receiving a response from you.
Write a new comment
<strong>,<em>,<cite>and<code>. Links, email addresses and line breaks are parsed automatically.