MLNTN

Maniacal musings of a pixel perfectionist

Archive for December, 2007

Method overloading

Posted by Jared On December - 4 - 2007

John Resig, one of my heroes and creator of the jQuery JavaScript library, wrote a great piece about overloading methods. He created a dead simple function that shoulders most of the work. Check it out:

function addMethod(object, name, fn){
  var old = object[ name ];
  object[ name ] = function(){
    if ( fn.length == arguments.length )
      return fn.apply( this, arguments );
    else if ( typeof old == 'function' )
      return old.apply( this, arguments );
  };
}

Here’s how you could use it to extend the User object that we created earlier.

addMethod(User.prototype, "find", function(){
  // Find all users...
});
addMethod(User.prototype, "find", function(name){
  // Find a user by name
});
addMethod(User.prototype, "find", function(first, last){
  // Find a user by first and last name
});

You can read more from John’s blog here.

Creating objects and methods

Posted by Jared On December - 1 - 2007

That’s right, object-oriented Javascript. Let’s get to it. We’re going to make an object for storing and retrieving user information.

Let’s start with the base object:

var User = function(firstName, lastName, emailAddress) {
}

We have to initialize the variables so that they’re available to the rest of the methods of this object:

var User = function(firstName, lastName, emailAddress) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.emailAddress = emailAddress;
}

Then let’s start creating the methods:

User.prototype = {
  add: function() {
    alert('User added: ' + this.getFullName());
  },
  changeEmail: function(email) {
    this.emailAddress = email;
    alert('E-mail address for '+ this.getFullName() +' changed to: ' + this.emailAddress);
  },
  getFullName: function() {
    return this.firstName + ' ' + this.lastName;
  }
}

Lastly, let’s run the

add()

method when we setup a new user:

var User = function(firstName, lastName, emailAddress) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.emailAddress = emailAddress;
  this.add();
}

Alright, that’s all done. Now what do we do with this thing?

// alerts 'User added: Michael Bolton'
var michael = new User('Michael', 'Bolton', 'mbolton@initech.com');
// alerts 'E-mail address for Michael Bolton changed to: michael.bolton@initrode.com'
michael.changeEmail('michael.bolton@initrode.com');
// alerts 'Hello, Michael'
alert('Hello, ' + michael.firstName);

Here it is in one big snippet:

var User = function(firstName, lastName, emailAddress) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.emailAddress = emailAddress;
  this.add();
}

User.prototype = {
  add: function() {
    alert('User added: ' + this.getFullName());
  },
  changeEmail: function(email) {
    this.emailAddress = email;
    alert('E-mail address for '+ this.getFullName() +' changed to: ' + this.emailAddress);
  },
  getFullName: function() {
    return this.firstName + ' ' + this.lastName;
  }
}

// alerts 'User added: Michael Bolton'
var michael = new User('Michael', 'Bolton', 'mbolton@initech.com');
// alerts 'E-mail address for Michael Bolton changed to: michael.bolton@initrode.com'
michael.changeEmail('michael.bolton@initrode.com');
// alerts 'Hello, Michael'
alert('Hello, ' + michael.firstName);

Recursively parse XML into an array

Posted by Jared On December - 1 - 2007

Flash does not make it easy to handle XML. I’ve used some really bad code to help me parse arrays until I came up with this. It doesn’t handle elements of the same name at the same level, but it can probably be modified to do so.

var myParsedXML = new Array();

var myXML = new XML();
myXML.ignoreWhite = true;
myXML.onLoad = function(success) {
  if (success) {
    parseXML(myXML);
  }
};

myXML.load("data.xml");
function parseFile(xmlData) {
  var mainXMLElement = xmlData.firstChild.childNodes;
  for (var i = 0; i < mainXMLElement.length; i++) {
    myParsedXML.push(intoArray(mainXMLElement[i]));
  }
}

function intoArray(xml_element){
  var xml_array = new Array();
  if (xml_element.hasChildNodes()) {
    for (var cn = 0; cn < xml_element.childNodes.length; cn++) {
      if (xml_element.childNodes[cn].nodeType == 1) {
        xml_array[xml_element.childNodes[cn].nodeName] = xml_element.childNodes[cn].firstChild;
        if (xml_element.childNodes[cn].attributes) {
          xml_array[xml_element.childNodes[cn].nodeName].attributes = xml_element.childNodes[cn].attributes;
        }
      }
      else {
        xml_array[xml_element.childNodes[cn].nodeName] = intoArray(xml_element.childNodes[cn]);
      }
    }
    return xml_array;
  }
}