Random thoughts on JavaScript. Part one of who knows. The basics.

Screenshot fomr the movie The NetThis is going to be some sort of article on JavaScript. I’m still not sure exactly what will come of this, which means that now is your time to turn back. I won’t give you any more chances! Here’s something to keep you entertained while you think it through. And you may have to increase the volume while you watch it as it is just that mind numbingly awesome.

Still here? Cool. I wouldn’t be, but you know, to each his own.

People much smarter and more patient than me has written a lot about JavaScript. I guess that link should suffice as an article, but that would be a bit of a cop out on my part so I think I’ll give writing some random thoughts a try. It may just be a couple of pointers or tips. Or not. Hold my hand as we take the leap into the unknown.

First off, you know that you can try out your JavaScript online, right? Good. Now, let’s start with some JavaScript basics. And I mean really basic stuff.




Comment your code, but don’t go crazy with it.

var i = 0; // Declare i and set it to zero

A bag full of hurt. Use the good ol’ double slash for single line comments as per above. Use block comments for documentation or commenting out pieces of code.

/*
This is commented out
Isn't this pretty?
*/

Notation, notation, notation

In JavaScript, you can access properties of objects in two ways; square bracket notation and dot notation.

mySweetObject["property"] // Square bracket notation
mySweetObject.property // Dot notation

It may be tempting to use the dot notation as it’s a bit easier to type – because all coders are lazy, right? The downside of dot notation is that the property name is hard coded and thus can’t be altered at run time. Bracket notation, however, means that the property name is a string that gets evaluated. This means that you can use a variable, a hard coded string or a function call.  Also, should the property be generated at run time, a bracket notation is required. Let’s start with a silly little example and say that you have a number of properties named “myValue1″, “myValue2″, “myValue3″ and so on. For some reason you need to loop through these properties using a for loop. If you try to access these properties like this

mySweetObject.myValue+i

you’ll fail. What you need is

mySweetObject["myValue"+i]

Boom, you’re in. So for the sake of consistency, use square bracket notation. Consistency is good. Repeat as a mantra.

Typecasting

The wonder that is JavaScript is weakly typed which means that you do not need to cast, or define, the type of data you are using. JavaScript, or rather the runtime system, performs automatic adjustments so you do not need to worry about it. This is either a good thing or a bad thing, depending on your background. Good for new programmers, bad for people used to C or Java (any language with strong typing). There are however times when it can be useful to typecast, such as when you are working with both strings and numbers. Since the plus sign is used both for string concatenation as well as regular addition, you might get some unexpected results. You can cast to three different types – Boolean, Number and String.

myBoolean1 = Boolean(666); // true
myBoolean2 = !! 666; // true
myString1 = String(666); // "666"
myString2 = "" + 666; // "666"
myNumber1 = Number("666"); // 666
myNumber2 = 1 * 666; // 666

You can try it out and make sure that it really gets typecasted by alerting with the help of typeof.

alert( typeof(myBoolean2) );

If we’ve behaved, that should alert “boolean”. The Boolean type returns true when the value passed to it is a string with at least one character, a number other than 0 or an object. E contrario it returns false when passed an empty string, the number 0, undefined or null. Number converts the entire value to a number, as compared to parseInt() and parseFloat(). The latter methods will only convert up to the first invalid character they encounter in a string. “6.6.6″ with parseInt() becomes “6″ and becomes “6.6″ with parseFloat(). Make a good habit of defining the radix with parseInt(). The second argument that you can pass to it and allows you to  convert strings in binary, octal, hexadecimal or any other base into an integer. This may also be a good time to read up on floating point values. With Number() you get a “Not a Number” error, or the dreaded NaN. String should be a no-brainer. It’ll convert the value you want to a string, simple as that. What it does is call the toString() method. Note that String() will not result in an error for a null or undefined value – instead you get the string “null”.

Reserved words

This is something that can cause some confusion. I don’t know why, but I’ve seen my fair share of code where a developer uses a reserved word as a property name. It makes me kind of sad. The list of reserved words is a rather long one and pasting it here would just take up a lot of space, so instead I’ll just link to a page that has already done the dirty work. Please, please, please note the words that are reserved for future use, in the brand spanking new JavaScript 2.0 *cough* ECMA Script 4.0 *cough*. This will also leads us to…

Naming

See, there are limitations on the way can name things. You may use upper and lower case letters (a-z and A-Z), digits (0-9), and the underscore character (_). Although you can use other characters, it may break in certain cases. Better safe than sorry, right? Avoid starting names with the underscore character as it’s not rarely used to indicate privacy (more on that later on). Note that it doesn’t in itself create privacy.




Declare your variables

We know that JavaScript doesn’t require them to be declared, but, really, is it that hard? No. There is no excuse not to. You declare a variable with the use of the var keyword. Side note: If you come from C, you may need to know that JavaScript does not have block scope so be a good guy, and declare all your variables at the very top of your functions.

var myVar;
var myOtherVar = myRandomValue;

It makes it so much easier to identify undeclared variables that may, brace yourself, be implied globals. Implied globals can cause mayhem (mayhem as in a-minor-inconvenience-I-need-to-shape-up-my-code, not as in genocide). You see, the global object is the one namespace to rule them all. It holds, as you may have gathered by now, global variables and top level functions. It doesn’t take a mastermind to realize that collisions may occur and those collisions are part of the mayhem mentioned earlier. It will break your code. Basically, all JavaScript files you use run in the same scope which means that if you use globals, implied or not, and a script that loads after yours use the same variable or function names, the latter will replace your variables and functions. And that’s not good, is it? On a related note, you can declare multiple variables using a single var keyword and a comma separated list or variables.

var myVar1 = "Random",
    myVar2 = "Ramblings",
    myVar3 = "Fun stuff", myVar4, myVar5, myVar6;

Going global

Let’s back up for a moment and remember that in JavaScript, everything is an object. Or rather, a property of an object. In turn, an object is basically a collection of name-value pairs. The names are strings and values can be objects, numbers, booleans and strings. And a quick note on terminology – if the value is a function, strictly speaking, it’s called a method. But what about those functions, you ask? I’ve seen those around the code, you say. Well, those are actually properties to the window object.

function myFunction(myString) {
    alert(myString);
}

This little nifty function that alerts the variable string, actually means that we assigned a Function instance to the myFunction property. Functions do not have names. Actually, myFunction is a property of the window object. Does that make sense? It may be a bit more clear if we type it like so:

window.myFunction = new Function('myString', 'alert(myString)');

Feel a bit better now? Standalone functions are bound to the window object. When you would like to execute myFunction, you would normally type

myFunction('alert this string');

Nothing fancy. This can also be written as

window.myFunction('alert this string');

Remember, we are now dealing with global objects, which is in general a no-no, but nice for a simple explanation. Do you remember how we declared variables? When we type something like

var myVar = 'My string'

we are using a shorthand syntax (object literal – more on that a few lines down) for

var myVar = String('My string');

And these are also in the window object, i.e.

window.myVar = 'My string';
window.myOtherVar = String('My string');

Literal this, literal that

Thankfully, there are ways around the problem of collisions. One way is to employ object literals (see, I told you we’d get there) which basically means that you can define your own namespace (read: object or, going with OOP terms, a Constructor. Please note that it is Good Practice™ to capitalize the Constructor. I won’t in this case, because that’s just how i roll) and play with it. Or, as specified by the good people at Mozilla:

An object literal is a list of zero or more pairs of property names and associated values of an object, enclosed in curly braces ({})

Take this super simple example;

var myNameSpace = {
    myFunction:function(data) {
        alert(data);
    }
}

If you now try to call

myFunction('Alert this, you douche');

it will fail, as there is no property called myFunction in the window object. Instead, you need to call it using

myNameSpace.myFunction('Alert this, you douche');

That works just fine and if a script later on also has a myFunction() (preferrably in its own namespace), there will be no collisions. Goodie! The drawback of this technique is that you always have to go through the name of your object, or namespace. The solution would be to wrap your object in an anonymous function (or lambda). This will protect the scope. Our little snippet above would be typed like this:

var myNameSpace = function() {
    function myFunction(data) {
        alert(data);
    }
}();

Note the addition of the parenthesis on the last line and the ending semicolon. Also, you don’t need to stray away from the use of function myFunction() if that feels more comfortable. The parenthesis at the end makes the anonymous function execute right away. This is called the Module Pattern. This has the downside – or upside depending on your goals – of making myFunction() only available from within myNamespace. Any outside calls will fail (except maybe…). To fix this, you need to make a publicly available return statement.

var myNameSpace = function() {
    return {
        myFunction:function(data) {
            alert(data);
        }
    }
}();

Isn’t this fun? myNameSpace.myFunction(‘hey’); gets you going aaaand you’re pretty much back where we left off. Let’s alternate the example;

var myNameSpace = function() {
    function myFunction(data) {
        alert(data);
    }
    return {
        pointer:myFunction
    }
}();

See what we did there? We switched back to the other syntax for the private method and returned a pointer to that method instead. In this case, we call our function with

myNameSpace.pointer('hey');

Pretty sweet, right? The pointer can be as short as you want it and the private function can have any name you want, if that’s your preference. It makes me cringe a bit to mention public and private methods when dealing with JavaScript, but what the hell. Private methods or members are those that are created within the constructor. In the example above, myFunction is only accessible within the constructor myNameSpace and is returned only with the pointer or alias.

The reason that this works is due to the fact that JavaScript has closures. In essence, this means that a function defined within a function always has access to the vars and what have you of its outer function. Think about that for a while. That’s power, right there. Note that private and privileged methods can only be made when the object in questions is constructed. Public methods on the other hand, can be added ad hoc.




Friends with privileges

Although it might not be obvious, you also have the ability to create privileged methods. Privileged methods are accessible from outside the scope and can access private methods and variables. While you can delete or replace a privileged method, you can’t alter it. This is where you use the keyword this. This points to the method calling object.

function Constructor(data) {
    this.name = data;
}

This means that if we now construct a new object like so

var myConstructor = new Constructor('Gandhi');

myConstructor.name is “Gandhi”. Let’s expand.

function Constructor(data) {
    this.name = data;
    this.fetch = function() {
        return this.name;
    }
}

Okay, what can we do with this little gem of a function? Test it out with something basic like

var myConstructor = new Constructor('Gandhi');
alert( myConstructor.fetch() );

Did it work? Nice. It didn’t? Fail. Try again. Also try these quick examples:

var myConstructor1 = new Constructor('Gandhi');
var myConstructor2 = new Constructor('Shiva');
alert( "myConstructor1's name is "+myConstructor1.fetch() );
alert( "myConstructor2's name is "+myConstructor2.fetch() );

Did it work? Sweet. That’s about all I have to write for now. Fret not, there will be many more random thoughts coming quite soon, and not just on JavaScript. I’d like to leave you with an awesome talk from the JavaScript guru Douglas Crockford. Embedded below is a 45 minutes talk on Quality. It’s a good watch and, trust me, you’ll learn something new. It’ll make your code look better.


Douglas Crockford: “Quality” @ Yahoo! Video

No related posts.

Page 1 of 11
  • What is this?

    My name is William and I'm a 30 year old developer/designer from Stockholm, Sweden. I have a love/hate relationship with PHP, I'm slightly aroused by jQuery and if I had the Adobe Flash IDE as a friend on Facebook, I'd label it as "it's complicated". This is my twelfth year as a freelance monkey. I prefer the term mercenary, but someone said it had a negative ring to it. Whatever. Oh, and I'm a Mac guy who loves his BacBook Pro in a somewhat unhealthy way.


    The font used for headings is Geometry Soft Pro as found on dafont.com.