Archive for the ‘javascript’ Category

Video: John Resig – Testing, Performance Analysis, and jQuery 1.4

Monday, December 21st, 2009

In case you hadn’t seen it yet, John Resig was kind enough to stop by Yahoo! for the December Bayjax meetup. Here’s the video:

Usually developers are more interested in just getting the dang code to work, and as a result actual the testing and maintenance of JavaScript isn’t talked about too much, so I’m sure this will be new territory for many developers. And since it’s John Resig speaking, there was of course a bit about using TestSwarm, a testing distributed framework-agnostic automated testing tool (that’s a mouthful!).

Included in the talk are good things to note while testing, such as the fact unless you’re running Firefox or Chrome on Windows, all test times have a margin of error of up to 15ms (not to be confused with PPK’s observation of the delay between JavaScript computation and browser rendering).

(via YUIBlog)

JavaScript tidbit: special variables ($, $$, _, etc)

Tuesday, December 8th, 2009

You’re probably used to typical variables names such as the following:

var personName = 'Joe';

You may not realize it, but there are some non-alphanumeric variables at your disposal.

Using $

For instance, the $ variable has been made popular by several JavaScript libraries, most notably jQuery. You can use it to alias operations that are commonly performed, such as the following (1):

var $ = document.getElementById;
var myElement = $('targetElement');

If you declare this variable outside of a function it will be a global variable and will compete with libraries that use the same global variable, so it’s probably best not to use it.

Interestingly, originally the dollar sign $ was originally intended for “mechanically generated code” (2), but as the usage of the symbol has become popular for other purposes, it looks like the latest version of JavaScript (ECMAScript 5th edition) now officially “oks” its use:

This standard specifies specific character additions: The dollar sign ($) and the underscore (_) are permitted anywhere in an IdentifierName.

Using $$

Some have come up with the solution of simply using two or more $$ symbols in order to distinguish the variable from libraries that just use a single $:

var $$ = document.getElementById;
var myElement = $$('targetElement');

Using _

You will find that you can use the underscore _ in the same way to alias variables and functions:

var _ = document.getElementById;
var myElement = _('targetElement');

Other symbols

If you’re really getting adventurous, you can even try using other symbols such as square root √, which seems to work just fine, just as $ and _ above. The only problem: it’s quite inconvenient using it, since it’s not available on any keyboards (except through some crazy key combinations perhaps).

Or you can put the symbol to use doing what you would naturally think it should do…

var √ = Math.sqrt;
alert(√(4));   // 2

References

(1) Even Faster Web Sites, p. 128
(2) Stackoverflow: Why would a javascript variable start with a dollar sign?

Ways of passing data to functions in JavaScript

Friday, December 4th, 2009

Passing data is quite important in functional programming languages like JavaScript. When there are multiple functions (which is most of the time), there needs to be a way to pass data between the functions. This is done by passing values in parenthesis: myFunction(myData). Even when there is no data to be passed, we still have to declare and execute functions by using parenthesis: myFunction().

Simple Passing

I’ve already referred to the common method of passing data. Here’s an example of the code in action:

function greeting (name) {
    alert('Hello ' + name);
}
var personsName = 'Joe';
greeting(personsName);  // Hello Joe

This example only passes one variable to the function. Note that we can get rid of the variable personsName and make the string on the fly. So the code above is equivalent to this:

function greeting (name) {
    alert('Hello ' + name);
}
greeting('Joe');  // Hello Joe

Ok. Now let’s suppose we have a function that accepts two variables:

function greeting (firstName, lastName) {
    alert('Hello ' + firstName + ' ' + lastName);
}
greeting('Joe', 'Schmoe');  // Hello Joe Schmoe

This doesn’t look too hard. But there’s a catch – the person writing the code has to remember the order of variables to pass in. Suppose they call the function like this:

function greeting (firstName, lastName) {
    alert('Hello ' + firstName + ' ' + lastName);
}
greeting('Schmoe', 'Joe');  // Hello Schmoe Joe

That’s no good! This isn’t the result we want. In the case of firstName and lastName the variable order isn’t too hard to remember, but in other cases the variables aren’t in any logical order, which can cause confusion.

No constructor overloading

Unlike other languages such as C++ and Java, JavaScript has no constructor overloading. In fact, JavaScript is (for better or worse) not even strict about enforcing the number of variables passed in. For example, the following code works fine and throws no errors, even though we’re not passing in a variable in the function call:

function test (someVar) {
    // do stuff
};
test();  // no errors!

It’s only when you try to use someVar within the function that causes the problems. Otherwise, everything’s working just fine and dandy.

What happens if we try the other case scenario: pass in more variables than the function expects? No errors again:

function test () {
    // do stuff
};
test('testing 123');  // again, no errors

And what happens if we try to declare a function with the same name? No errors, but the previous function is overwritten (this is generally to be avoided of course):

function test () {
    alert('First function');
};
function test () {
    alert('Second function');
};
test();  // Second function

Because JavaScript has no function overloading, all it takes to overwrite another function is to redeclare a function with the same name. It doesn’t matter what sort of arguments they accept.

Passing with the help of the arguments object

As it turns out, JavaScript has a handy arguments object to access the arguments passed into each function:

function test () {
    alert(arguments[0]);    // testing 123
};
test('testing 123');

In the above case the arguments object acts just as an array – it’s 0-indexed and can be used to access any arbitrary number of arguments. But arguments also has an interesting and useful property: length. Using arguments.length, we can traverse the array of arguments. This is handy in cases where we might want to add an arbitrary number of elements together:

function add () {
    var sumTotal = 0;                        // initialize total to 0

    for(var i=0; i<arguments.length; i++) {  // for each argument
        sumTotal += arguments[i];            // add current argument to total
    }

    alert(sumTotal);
};
add(2, 3, 4);  // 9
add(1, 1, 1, 1, 1, 1, 1, 1, 1);  // 9

Passing an object

JavaScript libraries such as YUI have already learned that the variable order is a common nuisance and an opportunity to introduce errors, so they’ve come up with a solution: pass a single object to the function. It ends up looking something like this:

function greeting (obj) {
    alert('Hello ' + obj.first + ' ' + obj.last);
}
var nameObject = {};
nameObject.first = 'Joe';
nameObject.last = 'Schmoe';
greeting(nameObject);  // Hello Joe Schmoe

Now the variables become properties of a single object which is passed into the function. And it doesn’t matter which order the properties are declared in, which is a great relief to the developer.

Note that we can simplify the above code:

function greeting (obj) {
    alert('Hello ' + obj.first + ' ' + obj.last);
}
var nameObject = {
    first: 'Joe',
    last: 'Schmoe'
};
greeting(nameObject);  // Hello Joe Schmoe

And we can simplify even further:

function greeting (obj) {
    alert('Hello ' + obj.first + ' ' + obj.last);
}
greeting({
    first: 'Joe',
    last: 'Schmoe'
});  // Hello Joe Schmoe

This is the form commonly used in these JavaScript libraries. It’s easy to copy-and-paste example code, but it might not always be so obvious what’s going on behind the scenes. You can see that just as we bypassed declaring a named variable in the Simple Passing model (with greeting(”)), here we use the same shortcut and bypass declaring a named object (with greeting({})).

call() and apply()

These two methods have different techniques for passing data to functions, but I’m going to have to hold off on them for now. It’s a bit complicated, since they’re only used to execute methods (functions) in other object contexts. But seeing as I need to explain object context to get into that, I’ll save that for a future entry!