Blog of Jeff A blog about programming and random other things.

30Jun/09link

“Brief” Guide to JavaScript – Part 4

Here we’re covering Arrays & Objects. I’m also testing out the some code display plugin for Live Writer. It’s not perfect, but it's better than no color.


Arrays

Arrays are a typical programming paradigm. It allows us to store multiple values into one variable, usually the values are related in some way or another. Let's say we want to store a list of our grades for a particular class:

var grades = [80, 93, 66, 97];

If we want to access individual elements of the array, we use a number that represents where its located in the list, where zero is the first element.

alert(grades[0]); // displays 80
alert(grades[1]); // displays 93
alert(grades[2]); // displays 66
alert(grades[3]); // displays 97

Grades stores an array which contains 4 elements (not to be confused with html elements). We can verify the size of the array by accessing the length property.

var size = grades.length; // size stores 4 (assuming grades is the array from above)

This property is pretty handy if we wanted to calculate our average:

var average = 0; // set value
for(var i=0; i<grades.length; i++){ // i is from 0 to 3
    average += grades[i]; // we add the grade at i to average
}
average /= grades.length; // divide by the number of grades

Here, we utilize our handy friend, the for loop, and use i which increments by one starting at zero (where our first element would be) to the length of grades minus one (where the last element would be). This allows us to access each element in grades. We then add each element we access to our average variable before dividing by the total number of grades. Cool huh? :)

Using an array saved us all the effort of manually adding each grade if we stored each grade as an individual variable.

Arrays are more than a static list. Like any other variables, we can also assign new values to array elements:

grades[2] = 101; // the evil people we are, upping our grades :) 

We can just as easily add new grades at the end of the array:

grades.push(86); // now grades[4] has 86

An alternative is to do this:

grades[grades.length] = 86;

And remove grades from the end of the array if we wanted to:

// removes the grade we just added earlier. Stores 86 to last_grade.
var last_grade = grades.pop();

It's also worth noting that elements in an array can be any kind of data:

var mylist = ["web", 2.0]; // perfectly fine
alert(mylist[0]); // displays web
alert(mylist[1]); // displays 2.0

There are more methods and properties which you can read over at W3Schools if you have a curiosity to feed.

Objects

Nearly everything in JavaScript are represented as basic types (string, int, float, etc.), functions, or objects. The special feature of objects is that it can house more data.

Objects are broken down to two things: keys and values. If you're coming from another programming language, objects are similar to hashes or dictionaries.

Let's say we want to store a simple address book:

// john & tina are called keys, while the phone numbers are called values.
var book = {john: "123-456-7890", tina: "098-765-4321"};

Here book stores two people: john and tina and their phone numbers (as strings). We can access the phone numbers like so:

alert(book.john); // displays john's phone number
alert(book.tina); // displays tina's phone number
alert(book['john']); // also works. displays john's phone number

Any property we didn't assign are undefined (like unassigned variables):

alert(book.joe); // undefined

Like arrays, we can add new people quite easily:

book.bob = "200-300-1337";
book.cathy = "444-555-6666";

We can iterate over the each name using a modified version of a for loop, aptly named the foreach loop.

for(var name in book){
    // prints "<name>'s phone number is <phone number>"
    // for each person in our address book
    alert(name+"'s phone number is "+book[name]);
}

The foreach loop can also work in arrays. The variable we provide in the foreach loop will be the index number the element is located

var arr = [1, 2, 3, 4, 5];
for(var i in arr){
    // displays 1, 2, 3, 4, 5 in their own alert boxes
    alert(arr[i]);
}

We can use objects in conjunction with anonymous functions for something more complex than our simple address book.

var myContainer = {
    items: [],
    length: 0,
    push: function(item){
        myContainer.items.push(item); // adds to our list.
        myContainer.length = myContainer.size();
    },
    size: function(){ return myContainer.items.length; }
};
myContainer.push('hello'); // add item
for(var i=0; i<myContainer.length; i++){    // alerts out all items in array, which is only 'hello'

    alert(myContainer.items[i]);
}

This simply encapsulates an array through our object. We can access the array directly, but we can also call any associated functions. If you plan on creating classes (see Object-Oriented Programming), I don't recommend you to do this unless you intend on creating static classes.

As a sidenote, keys can be more than just alpha numerical values, you can use almost any character, but you must enclose them as strings:

var addressbook = {
     'john-fredrick': '123-456-7980'
};
// this doesn't work: 
addressbook.john-fredrick
// this does: 
addressbook['john-fredrick']

 


We’ll that’s it for this week. Next we’ll get an overview of the DOM tree. As always, utilizing what you learn is the best way to retain the knowledge. Read part 5.

  • Share/Bookmark
23Jun/09link

“Brief” Guide to JavaScript – Part 3

Before I continue this article, I'll emphasize that I'm open to comments and corrections. I apologize if I don’t get back to you, I have a job with a long commute times (~2 hours), but I do read them. And now back to your program…


Global Scope

Variable assignments, like those from above, are stored in the global scope, that is, they can be accessed from anywhere in your code. For browsers, all the variables are automatically assigned to the window object. So if we declared the variables above, we can access them like this:

alert(myvariable); // works
alert(window.myvariable); // also works

Alert is a browser-provided function to display a simple message box with the given value. Like the variables, alert is in global scope and resides in the window object namespace. The window variable is an object provided by browsers which usually contain browser-specific functionality (such as alert).

A simple dialog created using alert.

Functions

Programmers are lazy, and retyping / copy & pasting code. It's too much effort. Doing so also makes code less flexible when we need to change something because then we need to change it for all the occurrences. That's why programmers like functions.

Since JavaScript is a functional language, functions are treated just like other data types (string, float, integer, etc.). An example function definition:

function tell(){
    alert("I'm telling on you...");
}

Like var, function definitions are put into the smallest scope possible. In this case, the global scope. We can run this function after we declared it by:

tell(); // runs alert("I'm telling on you...");
tell_copy = tell;
tell_copy(); // does the same thing as tell() above
window.tell(); // also works

Parameters

Functions, like the mathematical kinds, can accept extra parameters. This is done in the function declaration:

function say(msg){
   alert(msg);
}
say('hello world');

This provides the ability to customize what message we want to put. In reality, this is just an alias to the alert function. You can have more parameters, separated by commas.

function print_values(x, y){
    alert(x);
    alert(y);
}
print_values(500, 1200);

Returning Values

Mathematical functions return a value given. Programmatic functions can do the same. This is done with the return keyword.

function add(x, y){
    return x + y;
}
var sum = add(50, 20); // sum stores 70

Scoping

Another key attribute of functions is that they provide their own scope. I always find examples as the best way to explain things:

var globalvar = 'hello';
function myfunc(){
    var funcvar = 'world';
    anotherglobalvar = 'oh?';
    // globalvar, anotherglobalvar, & funcvar are defined here.
}
// funcvar is not defined here. but globalvar = 'hello' and anotherglobalvar = 'oh?'

As you can see, scopes help prevent us from stepping over ourselves all the time, but still allow access to variables outside of the scope. Which is pretty handy. We also see the side effect of not using var. Inside scopes, excluding the var declares the variable in the global scope. 99% of the time, this isn't what we want, so (to repeat again) it's best to use var.

You may say now, why can't I just remove the var keyword when I'm defining global variables? It's a matter of good practice (which seems to always fall on deaf ears of new programmers).

When you, or someone else, reads the code, it's easier to see variable assignment with a var and see: Okay, this person is defining a new variable, as opposed to just assigning a variable (which can make it hard to determine when a variable is created).

It's worth noting that curly braces in JavaScript do not provide scope:

if(true){
    var hello = 'world';
}
alert('hello');

This code runs just fine since the variable hello persists after the block ends. Likewise:

var j = 256;
for(var i=0; i<10; i++){
    var j = i * i;
}
alert(i); // outputs 10
alert(j); // outputs 81 (9 * 9)

Anonymous Functions

Functions are data types. And like any other data type, it doesn't need to be binded to a variable directly. This is accomplished simply by excluding the function name.

function() {
    alert('hello world');
}

At first glance, this isn't feature in JavaScript doesn't seem practical at all. And it isn't. We can't call this function. Obviously this isn't the correct way to use anonymous functions. We could replicate the same behavior as our previous function definitions by assigning it to a variable.

var tell = function(){
    alert('Tattle Tailing on You');
}
tell(); // call the function

It still doesn't seem very useful to have anonymous functions in this example. Let's see a more likely scenario:

function too_large(num1, num2, func){
    if (num1 + num2 > 10){
        func();
    }
}

This defines a function which accepts three parameters: two numeric values and one function. If the sum of both numbers is greater than 10, the passed function is called. We can define the function and then pass the function to too_large by specifying the name:

function mycallback(){ /* code */ }
too_large(5, 15, mycallback);

But that's the lousy method. We're cluttering our current scope with unnecessary variables that we use only once. Instead, we can use an anonymous function:

too_large(5, 15, function(){ /* code */ });

Many JavaScript frameworks utilize callback functions to allow framework users to plug in functionality in portions of framework code. You can also utilize it on events, special triggers that browsers fire, such as the window is resized, or the user types in something, etc.

Warning: anonymous functions shouldn't always be used willy-nilly, mostly due to performance issues. For example:

for(var i=0; i<5000; i++){
    (function(x, y){return x + y;})(5, 2);
}

Yes it's another useless function, but in each iteration of the loop, the function is first generate before being called. Not the best of things where as:

function add(x, y){return x + y;}
for(var i=0; i<5000; i++){
    add(5, 2);
}

This is faster than the previous since the function is only created once. Anonymous functions are powerful, but with great power comes great responsibility.

Don't worry, we'll talk more about anonymous functions in subsequent topics.

Edit: Part 4 is available.


That’ll wrap it up this week. We’ll cover the more advanced data types: Arrays and Objects, next week.

  • Share/Bookmark
16Jun/09link

“Brief” Guide to JavaScript – Part 2

Branching (Conditionals)

Majority of the time we want some logic in our code to figure out things to do. We don't want to attempt to hammer a nail if we don't have a hammer. Conditionals allows our programs to make decisions based the validity of a certain conditions.

If Statement

The simplest of all branching is the if statement.

if (expression){
    // code block
}

expression is a value that resolves to a boolean value: true or false. If false, the code block is skipped (not executed). True will execute the code block. But since JavaScript doesn't have strict data types there are some auto-converting done for you:

  • undefined, null, false, 0, NaN, empty string ('') convert to a false
  • everything else is true.

Here are some examples of various if statement examples:

var myvar = 'hello';
if (myvar){
    // the line below will be executed
    myvar = "truthy";
}

var myotherval = 0;
if (myotherval){
    // the line below will NOT be executed (expression evaluates to false)
    myotherval = 43;
}

More Expressions

Of course usually we want expressions that are more useful than the above. We can compare two values (or variables) using the following comparisons:

  • var1 == var2, compares if var1 equals var2. Returns true if equal and false if not. This auto converts types (so '0' == 0 is true)
  • var1 === var2, compares if var1 equals var2. Returns true if equal and false if not. This does not auto convert types ('0' === 0 is false).
  • var1 != var2, checks if var1 does not equal var2. Returns true if not equal and false if equal. This auto convert types ('0' != 1 is true).
  • var1 !== var2, like !=, but doesn't auto convert types.
  • var1 < var2, checks if var1 is less than var2, true if that's the case, false if otherwise.
  • var1 <= var2, like < operator but is less than or equal.
  • var1 > var2, like < operator but is greater than.
  • var1 >= var2, like < operator but greater than or equal.
  • expr1 || expr2, checks if expr1 or expr2 evaluates to true. If expr1 evaluates to true or expr2 evaluates to true, then || returns true, otherwise false.
  • expr1 && expr2, checks if expr1 and expr2 evalute to true. If expr1 is true and expr2 is true, then && returns true, otherwise false.

For || and &&, it's best to surround the expressions in parenthesizes () for visual clarity and ensure expressions are evaluated as you intended. For example:

a == b && c != d || e < f


Is pretty hard to figure out how the expression evaluates given the values for each variable. Heck, I don't even know. That's because it could be broken down to (expr1 && (expr2 || expr3)) or ((expr1 && expr2) || expr3). So using parenthesizes are good:

(a == b && c != d) || (e < f)


As a side note, since expressions are evaluated to a boolean value, you can assign a variable to an expression:

var var1 = (0 < 5); // true

&& || Oddity

The AND and OR statements (&& ||) behave slightly differently that I explained above (to keep it simple). In reality, values are returned. 2 && 3 is truth-y, but it actually evaluates to (The last value that the JavaScript engine checked). This works similarly to OR.

In comparison to most programming languages, this is an usual behavior.

Here's some more examples and their results:

2 || 3 => Returns 2

0 && undefined => 0

0 || undefined => undefined

0 && 1 => 0

0 || 1 => 1

Single-Statement If

If you only have one statement for the if statement block, you can exclude the curly braces {}:

if (expression)
    statement;


But beware, any other statements won't be in the if statement. It's best to avoid using this if you're new to programming (to prevent you from hours of headaches). Proper spacing helps you figure it out at a glance:

if (expression)
    statement;
statement;
statement;

It's clear from the spacing to see which statement is only executed if the if statement is true.

Elses, Else If's statements

Say you want to do something else if the first IF statement doesn't evaluate to true. That's what else if and else statements are for. They extend if statements, meaning they are appended after the if statement.

if (expression1){
    // codeblock 1
} else if (expression2){
    // codeblock 2
} else {
    // codeblock 3
}

If the expression1 is true then the two else codeblocks (2 & 3) are skipped. If expression1 is false then it moves on to the else if, evaluates to expression2. If expression2 is true, then the codeblock 2 is executed (and the other codeblocks are skipped). If both two expressions are false, then codeblock 3 is executed.

Else and else if statements are always optional (not required for if statements) and you can have multiple else if statements. If you use else and else if statements, else should always be at the end.

Ternary Operator

Sometimes you'll want and extremely concise if-else statement. There's even a shorter one-liner method that is formatted as:

expression ? true_statement : false_statement

Several use cases are for variable assignments:

// Using parenthesis makes it easier to read
(b == c) ? (a = 3) : (a = 2);
// alternatively (also works)
var a = (b == c) ? (3) : (2);
// both above are equivalent to
if(b == c)
    a = 3;
else
    a = 2;

Repetition (Loops)

Sometimes you'll do things that is repetitive or operations that need to repeat until a certain condition is met. That's where we can utilize loops.

While

While loops continuously execute a given code block provided that an expression evaluates to true.

while (expression){
    // codeblock
}


Usually the codeblock modifies a value that affects expression, otherwise you get something like this:

while (true){
    // codeblock
}

Which loops to the end of time. Not so good. Luckily, most browsers will warn you of this after some time.

Firefox dialog when the script runs for awhile. Usually a infinite loop issue.

If the while statement is false, the code block is not executed. This includes if the code block was never executed to begin with.

Do

If you want your while loop to always execute at least once, you can do something like this:

var first = true;
var counter = getSize(); // pretend function
while(first || counter > 10){
    // do stuff
    counter++;
    first = false;
}


But you can use do to simplify your code:

var counter = getSize(); // pretend function
do {
    // do stuff
} while(counter > 10);

Although I'll admit, do is less common as while or the next looping construct we'll talk about.

For

A common use of while loops is a counter-style method.

var i=0;
while(i < 20){
    // code here
    i++; // increments i by 1
}


For brevity, we can use the for loop to do the same thing:

for(var i=0; i<20; i++){
    // code here
}


For loops are basically broken down into this:

for(statement1; expression; statement2){
}


statement1 is executed before the loop begins. expression is checked before every loop (to see whether or not to run the code block. statement2 is executed after the code block finishes executing. It's worth noting that your variable that you use in the for loop overrides any value you set it before the for statement.

var i=22;
for(var i=0; i<5; i++){}
// i = 5

For historical & convenience reasons, i, j, and k are usually used as loop variable names.

Technically, you can have the statement slots empty, effectively making the for loop a while loop:

for(;val == 'loop'; ){/* do stuff */}

Edit: Part 3 is available.


That wraps it up for this week. Next week, we’ll cover some basics of scopes and functions.

  • Share/Bookmark

Recent Posts

Topics

Archives

Following

Links