Skip navigation.

halO

programming, hackery, rants, science and of course Opera

Posts tagged with "ecmascript"

Operator tricks

, , , ...

Operators behave mostly the same in many different languages, but in some you can use some nice tricks to save some space. For instance, in ecmascript you can assign a variable value from a deep tree without the risk of the script aborting because the array value was undefined.

var foo = c && c[0] && c[0][1];

The code will assign foo the value of c[0][1] or unassigned. The equivalent of this code is

var foo;
if(c)
   if(c[0])
      if(c[0][1])
         foo = c[0][1];

Boolean operators are conditional if you use && or ||. Using the AND operator, the following statements will not be executed if the current is false. Using OR, the same is true if the current is true. Here is an example using conditional OR

var foo = (bar < 10) || 5; // assigns 5 or true

You can use conditional operators as a shorthand of if. The last evaluated statement is the returned value.

Assignation

The assignation operator, =, does in fact return a value and is not always true. The assignation operator returns the value that was assigned, so foo=10 returns 10. This is the basis of how this effective loop works:

for(var n=0,e;e=array[n];n++){}

As long as the array contains values that are not evaluated as false in a boolean context, such as 0, '', false and probably a few others, it works fine. The reason is that the loop continues as long as the middle statement is true, and the returned statement is array[n].

Faster for-loops, update

, ,

In my blog entry about Faster for-loops i wrote about how to increase the efficiency of your for-loops. Virtuelvis pointed out an article at userjs.org with even faster for-loops (which was my original inspiration for the blog entry, but could not remember the source).

Example from userjs.org

var rows = document.getElementsByTagName('tr');
for( var i = 0, row; row = rows[ i]; i++ ) {
  row.className = 'newclass';
  row.style.color = 'red';
  ...
}

The code works by exploiting the fact that assignment of a variable returns the value the variable was assigned. Confusing you? Let's use an example. If you have a variable x and evaluate if(x = 5) it would be equivalent to evaluating if( 5 ). Since 5 evaluates to true in a boolean context, it would be equivalent to if( true ). Which boolean a value is evaluated as depends on the programming language, but most i know of consider 0 (zero), null and the empty string as false. The reason the above loop works perfectly is that as soon as the array goes out of bounds, it returns null and ends the loop before any harm is done.

So, we see that the loop assigns the current item to a variable and checks the assigned value in a boolean context for whether to continue or not. This works great if you are looping through a set of DOM elements for instance, but if the contents of the subject array is unknown you should be careful. Consider an array that contains the values 23, 56, 0 and 85. The loop would arrive at the third element and evaluate "row = 0", which evaluates to false in a boolean context and thus end there without reaching the fourth value.

The moral of the story is "If thou wishes to optimize thine code, know the contents of thy arrays" - or something like that...

Quicktags

, ,

Laziness is the mother of all inventions... I created a function in javascript which'd help me create DOM nodes quickly, here's the source:

/**
* Shortcut for creating a new html tag using JSON notation. 
* @param JSON The tag using JSON notation. The first value of the object 
*    is the tag name, second child is array of parameters and third child 
*    is array of children elements. If the first parameter is a string, the 
*    node is assumed to be a text node and has no further children.
*/
function quickTag(JSON){
  var elem;
  if(typeof(JSON) == 'string'){
    elem = document.createTextNode(JSON);
  } else {
    // Create the element itself
    elem = document.createElement(JSON[0]);

    // Add attributes
    if(JSON[1])
    for( attr in JSON[1] ){
      elem.setAttribute(attr, JSON[1][attr]);
    }

    // Add child elements
    if(JSON[2])
    for(var j=0;j<JSON[2].length;j++){
      elem.appendChild( quickTag(JSON[2][j]) );
    }
  }
  return elem;
}

Here's a quick example of the usage, hopefully you'll see what the syntax is fairly quickly. Note that the parameter uses JSON syntax, you might want to quickly read up on that if you're not too familiar with it. It's very simple and would only take a few minutes.

var p = quickTag(['p',{'class':'test'},["This is a ",['em',,'test']," node."]]);
document.body.appendChild( p );

The first item in the array is the tag name, the second is attributes and their values given as an object and the third parameter is child elements, which means that you can start all over again with a new array, or just pass a string to use as a text node. The above example would produce the output equivalent to

<p class="test">This is a <em>test</em> node.</p>

It has been tested and works with Opera 9 and Firefox 1.5.0.4, I don't have other browsers to test with right here right now, but I suspect Internet Explorer will throw a fit if trying to set class by setAttribute. It's always a hoot with that old thing...

A (Re)-Introduction to Javascript

, , ,

I stumbled across a nice paper which summarizes nicely the capabilities of the core functions in java/ecma -script. If you're new, or anything other than an expert, it might provide a nice reference. Combined with Quirksmode.org for an introduction to the correct philosophy (object-detection etc.), the two should provide for a good learning curve for newbies.