Saturday, October 13, 2007

Javascript Literal Notation: basics

Javascript offers different way to create arrays.
We will see how to create them by using the literal notation and see some advantages of this notation.

Arrays creation:the old way


Javascript offers a way to store multiple values in one variable.Each variable is associated with a number starting from 0.
This variable, containing several values is called an array.
Here is how you can create an array:
var words=new Array();
words[0]='hi';
words[1]='good bye';
words[2]='good morning';
words[3]=4;
You could define in the constructor new Array the number of values that will be stored:
var words=new Array(4);
The array will contain 4 slots ready to be used.
You could also defined the values directly in the Array constructor:
var words=new Array('hi','good bye','good morning',4);
This is shorter and you can access the value by their position in the array:
var words=new Array('hi','good bye','good morning',4);
alert(words[1]); // alert good bye
alert(words[3]); //alert 4
Remember that it starts from 0 and as you can see, the value are kept in the order you have written them!
You can change a value afterward too:
words[3]='good afternoon';
What was a number,4, is now the string 'good afternoon'.

Creating an array, gives you access to different properties and method:
alert(words.length); //4
alert(words.sort()); //4,good bye,godd morning,hi
alert(words.reverse()); //hi,good morning,good bye,4
alert(words.join()); //hi,good morning,good bye,4
alert(words.join('|')); //hi|good morning|good bye|4
alert(words.toString()); //hi,good morning,good bye,4


alert(words.slice(0)); //hi,good morning,good bye,4
alert(words.slice(0,3));//hi,good morning,good bye
alert(words.slice(2,3));//good bye
alert(words.slice(0,-2));//hi, good morning
alert(words.slice(0,words.length-2));hi, good morning
You also have functions/methods to add/delete element from the array:
alert(words.pop());//4
alert(words.shift());//hi
alert(words.push());//2
alert(words.unshift());//undefined
alert(words.splice(0,2,'good afternoon')); //good morning,good bye
You can read more about this subject here

Arrays creation: the new way


The new way is an addition to the old way, which means that you can still use the old way.
var words=[];
words[0]='hi';
words[1]='good bye';
words[2]='good morning';
words[3]=4;
or
var words=['hi','good bye','good morning',4];
which in the end allows to do the same manipulation as above!
This is shorter and allows you to nest arrays:
var words=['hi',['salut','heil'],'good bye',['au revoir','Auf Wiedersehen']'good morning',['bonjour','Guten Morgen'],4];
Then you can do this:
alert('english'+words[0]);//hi
alert('french'+words[1][0]);//salut
alert('german'+words[1][1]);//heil
That's nice!
But nested arrays are not very easy to deal with...
You have to remember that you have the english word followed by an array containing first the French version and then the German.
It is not very intituive that's why there is an other way to store multiple values in one variable.

Associative arrays or Hash or Dictionaries


I have written all the name you may encounter in different languages.
They all define the same base ideas, having the final implementation sometimes diverging from a language to an other.
As we have seen we can store several values in one variable thru arrays.
We can then call the value we need by referencing its position in the array.
But calling values thru their position is not very as friendly as it could be and if the order change, you will have to rewrite many things in your code.
It could be nice if we could set a name to the variables we store and then we could refer to this name instead of the position.
Basically an associative array associate a name with a value and store everything into one variable.
In javascript unfortunately, you don't have associative arrays!
But you have what is called object and we can use them to create some pseudo-associative arrays.
Why aren't they true associative arrays ?
Because you don't have access to all the functions and methods we have seen for the arrays!
Let's see how we can create an object in javascript.
They are many ways:
var dictionary=new Object();
dictionary.english=['hi','good bye','good morning'];
//or
dictionary['english']=['hi','good bye','good morning'];
dictionary['french']=['salut','au revoir','bonjour'];
dictionary['german']=['heil','Auf Wiedersehen','Guten Morgen'];
Then we can do the following:
alert(dictionnary['english'][0]); // return hi
alert(dictionnary['french'][0]); // return salut
alert(dictionnary['german'][0]); // return heil
So we created an object and stored into each language an array literal of each words.
But this is not very better than our nested arrays, we still need to refer to the value thru their position in the array.
If we can nest array literal, we can aslo nest object literals!
First let's see how to create a literal object:
var dictionary={};
Here you go, you have created your object!
To notice that literal notations don't give access to all the properties/methods you could have with the usual creation.
For objects, you won't have access to the prototype methods but for now, this is ok as this won't be a problem for our purpose.
Then we could rewrite the above like this:
var dictionnary={
     english:['hi','good morning','good bye'],
     french:['salut','bonjour','au revoir'],
     german:['heil','Guten Morgen','Auf Wiedersehen']
}
As you can see we separate each new property from their value by using ':'.

So now, how could we make our access to each words easier?
Let's nest object literals!
var dictionary = {
    hi:{
       french:'salut',
       german:'heil'
    },
    'good bye': {
       french:'au revoir',
       german:'auf Wiedersehen'
    },
    'good morning':{
       french:'bonjour',
       german:'Guten Morgen'
    }
};
Let's explain the above a little.
We create an object by using the literal notation, then we can enter some properties name. Instead of assigning a simple value to the property, we assign again a literal object! We are therefore nesting objects!
This is how we can then call the different words:
dictionary['hi']['french']; // salut;
dictionary['hi']['german']; // heil;
dictionary['good morning']['french']; // bonjour;
Here we don't refer to any position of the value, we refer to their property name, which allow to create more readable programs!

A good example of literal notation use:Function parameters


The problem

It often happens that you create a function that requires several parameters:
createElement(ElementType,idName);
This function will create an element according to the parameters.This is fine for now as it is just 2 parameters, easy to remember!
createElement('div','container');
But then you decide that it could be nice if we could set the width and height:
createElement(ElementType,idName,width,height);
//example
createElement('div','container',200,150);
This starts to be harder to remember the order of each element and if somebody reads the function call, he/she won't have any clue about what are the numbers 200 and 150.
This could be the widht and height or the height and width...
But it is still just 4 parameters, that's fine.
Then as you create div very often, you choose to set the div creation as the default behavior of your function and you add the colors:
createElement(idName,width,height,backgroundColor,color,elementType);
//example
createElement('container',200,150,'#FFFFFF','#FF0000');
//example
createElement('container',200,150,'#FFFFFF','#FF0000','p');
Here again, it is starting to be harder to remember the order of each element.
Sometimes you won't even need to set the background color so you will have to write:
createElement('container',200,150,'','#FF0000');
This is not that bad but you may have a typo miss like:
createElement('container',200,150,'#FF0000','p');
Did you really want to set the background color or did you just forget to skip the background color and then set the color? Here your color will be a paragraph element!!
Hummm...That's becoming hard.

Solution:use a literal object!

If you use a literal object, you will be able to write each parameters in the order you like and only if you need them!
var parameters={
     element:'div',
     id:'container',
     height:'200',
     width:'150',
     color:'#0000FF',
     'background-color':'#FFFFFF'
}
createElement(parameters);
//or 
createElement({id:'container',element:'p'});
The code is self-explainatory, you don't have to remember the position of each paremeters in the function call and it's really easy to have optional parameters!

Conclusion

We have seen how we can create literal arrays and literal objects and how we can use them in real programming problems!
Obviously, we didn't really explain the concept of object and we have seen a very basic use of them.
We will see in an other entry what are the principle behing objects and what you can do we them!

4 comments:

二狗 said...

A tiny mistake, missing a comma in the words definition. :)

-----------------------------
This is shorter and allows you to nest arrays:

var words=['hi',['salut','heil'],'good bye',['au revoir','Auf Wiedersehen']'good morning',['bonjour','Guten Morgen'],4];

二狗 said...

A question in below:

unshift() could be expected to return a new Arry.

Why did "undefined" alert in the code?

alert(words.pop());//4
alert(words.shift());//hi
alert(words.push());//2
alert(words.unshift());//why undefined?

Anonymous said...

Maybe you want to replace "heil" as the german word for "hi" with "Hallo", because "heil" is not in use any more since 1945

Anonymous said...

Please replace "heil" with "Hallo"!