Javascript takes a lot of flack for being prototypal vs class based which leads a lot of developers to incorrectly assume that OOP techniques like constructor chaining and inheritance aren’t possible. This couldn’t be further from the truth; the real issue is that Javascript didn’t used to include any native OOP style methods. Luckily however javascript still provided us enough power to be able to build these methods and techniques ourselves. It gets even easier when you are able to use ES5 Javascript; or for cross browser support use a framework like YUI which adds in the OOP methods missing from Javascript which I’ll be covering in a follow up post.

The first step is to understand that a constructor in Javascript is simply a function that you call with the word new. In the following example we are creating a function called Car, creating a color property on each instance of Car with the this special property, then creating a new instance of that function which is being assigned to the mustang variable.

function Car() {
    this.color = "red";
}
var mustang = new Car();
console.log(mustang.color); // Prints `red` to the console

The new keyword is very important when creating constructors in javascript. Without new Car will be executed and this will point to window creating global variables, and it’s return value will be assigned to mustang. In this case mustang will be undefined and if you try and access any properties on it your script will grind to a halt.

To be able to chain these constructors we will use one of two Javascript methods; call(), or apply(). These allow us to call another method in javascript but specify the scope to which it executes.

A common example to illustrate inheritance is creating a character in a video game.

function Baddie() {
  // Set up the baddies defaults
  this.level = 1;
  this.hitPoints = 100;
  this.name = "Baddie";
}

function Spider() {
  // Executing Baddie with it's context set to Spider
  // because we used `this` it now assigns it's properties
  // level, hitPoints, and name to the Spider instance.
  Baddie.apply(this);
  this.color = "red";
  this.legs = 8;
}

var regularSpider = new Spider();

console.log(regularSpider.level); // Prints `1` to the console
console.log(regularSpider.legs); // Prints `8` to the console

So here we have created two constructor functions, Baddie and Spider. The important line here is Baddie.apply(this); which executes Baddie in the context of Spider - adding those properties to the Spider instance. Using this technique you can chain as many constructors together as you like.

This is great but what if we need to create many different types of Spiders; we need a way to pass data from our instantiation down the stack.

function Baddie(config) {
  // Set the baddie defaults using the
  // supplied configuration values or the defaults
  config = config || {};
  this.level = config.level || 1;
  this.hitPoints = config.hitPoints || 100;
  this.name = config.name || "Baddie";
}

function Spider(config) {
  // This time we pass in a second paramter which
  // is the configuration object, or an empty
  // object if none was supplied
  config = config || {};
  Baddie.apply(this, arguments);
  this.color = config.color || "red";
  this.legs = config.legs || 8;
}

var regularSpider = new Spider(),
    // Pass a configuration object into the constructor
    superSpider = new Spider({
      level: 10,
      hitPoints: 10000,
      name: "Super Spider",
      color: "yellow",
      legs: 16
    });


console.log(regularSpider.level); // Prints `1` to the console
console.log(superSpider.level); // Prints `10` to the console
console.log(regularSpider.color); // Prints `red` to the console
console.log(superSpider.color); // Prints `yellow` to the console

With this example we are creating a super spider by passing a configuration object into the Spider constructor. For this to have any effect down the chain we need to add a second parameter to our apply() call. arguments is a special variable available in all functions which is an array-like object corresponding to the values passed to a function. This allows us to pass everything that was in the configuration object down to the next constructor.

If you remember a little earlier I mentioned we could also use the call() function. This function accepts an argument list instead of an array of values. So if you prefer to pass in values in this matter you would use call() instead of apply().

The last topic I want to touch on in this post is private properties and constructor methods using chained constructors. They are done pretty much exactly how you would assume coming from other languages but I’m going to illustrate the syntax just to drive it home. I have trimmed down the code a bit in this example to highlight the parts related to this topic.

function Baddie(config) {
  var id = "abc";

  // Code removed for brevity

  this.getId = function() {
    return id;
  };
  this.setId = function(newVal) {
    id = newVal;
  }
}

function Spider(config) {
  Baddie.apply(this, arguments);
  // Code removed for brevity
}

var spiderOne = new Spider(),
    spiderTwo = new Spider();

console.log(spiderOne.getId()); // Prints `abc` to the console
spiderOne.setId('123');
console.log(spiderOne.getId()); // Prints `123` to the console
console.log(spiderTwo.getId()); // Prints `abc` to the console

So as you can see in the Baddie function I created a local variable called id and assigned it a default value. I also created very basic getter and setter methods so that you can access this variable from outside of the function. Further down in the script I instantiate two completely separate spiders - they even have their own private id variable which is illustrated when I set it to 123 for spiderOne, but spiderTwo is still the default.

In coming posts I will be covering prototypal inheritance, YUI OOP, and new related Javascript methods but I’ll be sure to link them here. Thanks for reading! If you have any questions or comments you can comment below, or mention me @fromanegg. Till next time!

There is quite a bit of confusion in the beginner JavaScript world as to what the difference is between the keydown, keypress, and keyup events. So I hope that the following can help clear up some of the common questions as well as provide some solutions to make your life easier when dealing with cross browser key events.

As with all DOM events there is a generally accepted order to which they fire and key events are no different. When the user hits a key, the events are fired in the following sequence; keydown, keypress, keyup.

First we need some rules:

Click here to view this simple example on jsbin: Simple form validation on user input

var input = document.getElementsByName('currency-field')[0],
    currencyRegex = /^[0-9]{0,5}(\.[0-9]{0,2})?$/;

function handleKeypress(e) {
      // Get the string value of the charCode.
  var char = String.fromCharCode(e.charCode),
      target = e.target,
      inputVal = target.value,
      // Construct what the value will be if the event is not prevented.
      value = inputVal.substr(0, target.selectionStart) + char + inputVal.substr(target.selectionEnd);

  // Test to make sure the user is inputting only valid characters
  // and that the resulting input is valid.
  if (!char.match(/[0-9.]/) || !value.match(currencyRegex)) {
    toggleUI(false, target);
  } else {
    toggleUI(true, target);
  }

}

function handleKeyup(e) {
  var target = e.target,
      keyCode = e.keyCode;

  // If the user deletes anything, test the value in the input
  // again to check for validity.
  if (keyCode === 8 || keyCode === 46) {
    if(!target.value.match(currencyRegex)) {
      toggleUI(false, target);
    } else {
      toggleUI(true, target);
    }
  }
}

function toggleUI(valid, target) {
  if (valid === true) {
    target.className = "valid";
  } else {
    target.className = "warning";
  }
}

// On keypress or keyup, call their callback
input.onkeypress = handleKeypress;
input.onkeyup = handleKeyup;

This example should be fairly straight forward to follow along with but there are a few points of interest that relate to key events.

Click here to view this simple example on jsbin: Prevent invalid input on form

var input = document.getElementsByName('currency-field')[0],
    currencyRegex = /^[0-9]{0,5}(\.[0-9]{0,2})?$/;

function handleKeypress(e) {
      // Get the string value of the charCode.
  var char = String.fromCharCode(e.charCode),
      target = e.target,
      inputVal = target.value,
      // Construct what the value will be if the event is not prevented.
      value = inputVal.substr(0, target.selectionStart) + char + inputVal.substr(target.selectionEnd);

  // Test to make sure the user is inputting only valid characters
  // and that the resulting input is valid.
  if (!char.match(/[0-9.]/) || !value.match(currencyRegex)) {
    e.preventDefault();
  }

}

function handleKeydown(e) {
  var target = e.target,
      keyCode = e.keyCode,
      inputVal = target.value,
      value;

  // If the user deletes anything, construct the resulting
  // value to determine validity.
  if (keyCode === 8) {
    value = inputVal.substr(0, target.selectionStart - 1) + inputVal.substr(target.selectionEnd);
  }
  if (keyCode === 46) {
    value = inputVal.substr(0, target.selectionStart) + inputVal.substr(target.selectionEnd + 1);
  }    
  if (value) {
    if(!value.match(currencyRegex)) {
      e.preventDefault();
    }
  }
}

// On keypress or keyup, call their callback
input.onkeypress = handleKeypress;
input.onkeydown = handleKeydown;

You can see by this last example that by using keydown we can listen for the delete or backspace key, check the resulting input value, and if it’s invalid, prevent the user action.

As with anything front end related there are going to be cross browser differences so I highly recommend using one of the quality javascript libraries and frameworks available to normalize these differences for you. If you have read any of my other posts you have probably guessed that I’m partial to the YUI framework.

I hope that these examples not only show you how keyup, keydown, and keypress function; but also give you some ideas on the best situations to use them. If you have any questions feel free to comment below or mention me @fromanegg

If you have written anything using events in YUI you know that you have a few ways to listen to a single event on a target, two of the most popular are the on() and after() methods. Essentially the on() method allows you to listen to the event before the after() listeners are given a chance to react to it and after() allows you to listen after the on() callbacks have had a chance to execute.

If you use on() to listen for the attribute change event you will be notified every time something attempts to set the value of that attribute. If you use after() your callback will only be executed if the value set was successful. What this means is that if something else was listening using on() decided to prevent the change event your after() callback would never fire.

A useful side effect of this is that the after() callback will not fire if the value being set is identical to the one currently in the attribute. This means that if you have a situation where an attribute may be set multiple times but you only care when it changes - by simply switching to listening via the after() method your callback will only execute when the values differ. Saving you the code in the callback to check the values and the function call which now is only called when required.

Click here to view this simple example on jsbin: Using after() event listeners to react to attribute value changes

YUI().use('node', 'base-build', function(Y) {

  var body = Y.one('body');
  var Foo = Y.Base.create('foo', Y.Base, [], {

    initializer: function() {
      this.on('barChange', function(e) {
        body.append('change attempted');                                  
      });

      this.after('barChange', function(e) {
        body.append('change successful');
      });

      body.append("---> Setting bar to 'cupcake'");
      this.set('bar', 'cupcake');

      body.append("---> Setting bar to 'cupcake' again");
      this.set('bar', 'cupcake');

      body.append("---> Setting bar to 'pie'");
      this.set('bar', 'pie');
    }

  }, {

    ATTRS: {

      bar: {
        value: 'baz'
      }

    }

  });
  new Foo();
});

Thanks for reading, and if you have any questions feel free to comment below, mention me @fromanegg or pop into #yui on irc.freenode.net

Have something you would like to see on the next Hatched Links? Mention me on Twitter @fromanegg or find me in #yui on irc.freenode.net

Have something you would like to see on the next Hatched Links? Mention me on Twitter @fromanegg or find me in #yui on irc.freenode.net