An excellent post explaining JavaScript’s Object creation mechanism via prototype.

JavaScript, JavaScript...

(en Españolрусском中文)

JavaScript’s prototype object generates confusion wherever it goes. Seasoned JavaScript professionals, even authors frequently exhibit a limited understanding of the concept. I believe a lot of the trouble stems from our earliest encounters with prototypes, which almost always relate to new, constructor and the very misleading prototype property attached to functions. In fact prototype is a remarkably simple concept. To understand it better, we just need to forget what we ‘learned’ about constructor prototypes and start again from first principles.

View original post 894 more words

Advertisements

Forgiveness is a virtue (of Javascript)

Forgiveness and tolerance are Javascript’s greatest virtues: the language does everything it can to prevent errors and makes erroneous code work as much as it can. This is in huge contrast to ‘prima donna’ languages like C++ or Java(*1), which whine and cry at the slightest hint of error and do not hesitate at all to halt execution at the first opportunity.

Let us consider some examples. In the example below, we have a function that takes 1 argument. In the last line, I call the same function without any argument and the code works without any complains from the Javascript interpreter.

function foo(count) //a 1-arg function
{
    for (var i = 0; i < count; i++)
        console.log("count " + i);
}
foo(3); //call the function an argument
foo(); //***call the same function with no argument ***

Output

objects@london(umermansoor) $ node forgivenessVirtue.js
count 0
count 1
count 2

In fact the code above still works if we remove all semicolons (;)

function foo(count) //a 1-arg function
{
    for (var i = 0; i < count; i++)
        console.log("count " + i) //no semicolon
}

foo(3) //no semicolon here either
foo() //double whammy. Everything works

Note: Semi-colons are optional in Javascript and are required only if two statements occur on the same line.

Let’s look at a slightly advanced example. In Javascript, a constructor is a function that returns a reference to an object when called with new. E.g. var object = new SomeObject().

function Console(make) //a constructor
{
    console.log("The current make is: " + this.make + ". Setting make to: " + make);
    this.make = make; //setting make property of the object
}

var gamingConsole = new Console("Wii-U"); //normally that's how a constructor is called

Console("PS3"); //**calling a constructor directly, no complaints.

Note: If you are curious how the second example works when the constructor is called directly and there is no context for the this keyword. The answer is that Javascript uses the most global context in this case, normally the window object for web pages.

Why is Javascript so forgiving?

Javascript is THE language of the web. It is by far the most, popular language on the planet. I can even dare to bet that if you randomly pick two sites, there is a very high probability that both sites will be running Javascript in some form or fashion.

Javascript was designed to just work and this is the reason we don’t see sites running Javascript crash completely in the presence of errors. Your clients don’t come running to you complaining that the site is down entirely if there are Javascript errors. Please don’t get me wrong: Javascript programs can still contain irrecoverable errors, for example, missing closing “)” in a for statement. The point I’m trying to make is that Javascript will try very hard to prevent errors, but if errors are unavoidable, it will at least run the program as much as it can.

Javascript is very easy to learn and is fun to work with. I recall my first experience with Javascript when I was able to write a miniscule “Todo” program (or something like that) within an hour of first starting the language and the program just worked on the first try. This again is in sharp contrast with Java, which is very strict when it comes to discipline. When I started Java, for quite some time, I found it very difficult to write programs in plain text editor say vim without the assistance from an IDE say Netbeans, and run them without any syntactical errors on my first attempt.

Now back to the question: In my opinion, Javascript had to be forgiving in order for it be to widely adopted as the de-facto standard language of the web. This freedom however was mostly not intentional. Javascript is an outstanding Object Oriented (OO) language, however, it has more than its share of bad. A lot of different ways of doing the same thing, many different flavors, I can go on for hours talking about the bad parts of the language. In fact, there is an entire book on this subject: JavaScript: The Good Parts.

Summary:

Whether the freedom that Javascript lends to developers is a good thing or bad depends on the perspective. Beginners using Javascript as their first language love it. Veteran developers coming from background of disciplined language such as Java, may find themselves frustrated due to the fact that Javascript does not forces developers to behave themselves.

It seems to me that the freedom in Javascript is well balanced on the spectrum of most expressive languages like Perl and least expressive like Java. Javascript is an amazing OO language which is fun to work with, easy to use, and with the arrival of server side Javascript based platforms like Node.js, it can be used as the only language (not counting HTML + CSS) to furnish complete sites. (As opposed to PHP + JS, or Python+JS).

*1: Oracle/Sun Java is an extraordinary OO language. Java and Javascript were designed for two very different purposes, had different audiences and goals. Both are very good and popular in what they do. Context is the keyword here.
 

~~~ Ignore below this part ~~~~

Creating & Using Modules In Node.js & Understanding Paths

Javascript libraries are commonly referred to as “modules”. The modules are typically imported by other Javascript files to use their functionality. Modules could contain class definitions, or helper functions.

Node.js uses the global require() method to load modules. It is similar to import statement in Java or include in PHP. require is a Node.js function and is not part of the standard Javascript.

PHP’s include VS Node.js’ require

To include a file in PHP, we would do something like the following:

include 'filename.php';

To include a module in Node.js:

var module_name = require('filename.js');

The key difference is that PHP merges the content of the included file into current file’s scope. Whereas, in Node.js the contents of the imported module are accessible through the variable.

module.exports Object

A call to require() function returns module.exports object. The module.exports is automatically set to the same object as the module, so we can do something like this:

//filename: util.js
function add(num1, num2)
{
    return num1+num2;
};
exports.add = add;

This exposes the add() function to the world.

In the calling Javascript file, we can import and use the module as follows:

var utils = require('./utils'); // include the module we created

var result = utils.add(1, 2); // call the add function which was exported by the module
console.log(result); // prints 3

The name added to the exports object doesn’t have to be the same name as the internal function it is exposing. For example, consider the following code:

//filename: util.js
function addTwoNumbers(num1, num2)
{
    return num1+num2;
};
exports.add = addTwoNumbers; //Exposing addTwoNumbers() as add()

The calling script can do the following:

var util = require('./util.js');
util.add(1,2);

A common practice among Node.js developers is to use anonymous functions when exporting. Let’s take a look:

//filename: util.js
exports.add = function(num1, num2) { //exposes the anonymous 2-arg function as add
    return num1 + num2;
};

If you are wondering what is the difference between `export` and `module.exports`, it is nicely explained by Hack Sparrow:

Here is an eye-opener – module.exports is the real dealexports is just module.exports‘s little helper. Your module returns module.exports to the caller ultimately, not exports. All exportsdoes is collect properties and attach them to module.exports IF module.exports doesn’t have something on it already. If there’s something attached to module.exports already, everything onexports is ignored.

Node.js’ Import Path

Node.js uses a non-trivial algorithm when searching for a module specified in require() statement. Let’s look at several cases Node.js considers:

Case I: Absolute or Relative Path

This is the easiest case: If the path in require statement is absolute or relative, Node.js knows exactly where the module is located.

var moduleA = require('./moduleA'); // Module 'moduleA.js' is in the same folder as this script
var moduleB = require('../moduleB'); // moduleB.js is in the parent folder
var moduleC = require('/var/www/html/js/moduleC'); // absolute path

Case II: Core Modules

If the path (relative or absolute) is not specified, and the module that is loaded is one of Node.js’ core modules, it is automatically loaded. Node.js knows where the core module is located. The core modules are sys, http, fs, path, etc.

var moduleA = require('http');
var moduleB = require('fs');

Case III: No path and not core

This is where the algorithm uses non-trivial logic to locate the module, if you don’t specify path and the module you are loading is not a core module. For example:

var moduleA = require('myModule'); // no path given!

The module search algorithm in Node.js will attempt to find a directory called “node_modules”. It starts with the directory of the running script and will keep moving up the hierarchy (parent directories) until it locates the “node_modules” directory. When the node_modules directory is found, Node.js then looks whether the module is a .js file or is a subfolder. If the module is a .js (e.g. myModule.js), Node will simply load it. If there is a subdirectory called myModule/ (e.g. node_modules/myModule) then Node.js will attempt to load index.js or package.json inside the subdirectory. This looks confusing, let me use some illustration.

Going back to our example, suppose we require a certain module called “bigbangtheory”.

var moduleA = require('bigbangtheory'); // no path given!

Here’s how Node.js will look for it:

node_modules/bigbangtheory.js
node_modules/bigbangtheory/index.js
node_modules/bigbangtheory/package.json

The search will start in the same directory as the executing script and will work its way up the parent directories.

If the module is still not found, Node.js then uses “require.path” array, which lists include directory paths. The paths can be set using environment variable called NODE_PATH or programatically by scripts.