javascript functional class model

2008-08-08 @ 17:20#

a couple months ago, i started using the functional class model for javascript. instead of using class sample() to define a class, i use var sample function(). i like the way it looks and i like the way it feels. of course this is nothing new. i've seen several examples like this in the past. i finally got into the habit of using this pattern after reading Crockford's JavaScript: The Good Parts. it's an excellent book.

it took me a bit of time to get used to the public/private member pattern, but now that i have it under my belt, i just start thinking this way right out of the gate. it also seems to be to be a much better pattern (in Javascript) for establishing inheritance, too. you can pass objects in; use the aggregation pattern and return the results. not as 'verbose' as the prototype pattern, imho.

here's a little example that allows users to interact with a timer that fires off a private method within the class:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>funcitonal js model</title>
</head>
<body>
    <h1>functional js model</h1>
    <fieldset id="welcome">
      <legend id="status"></legend>
      <input type="button" id="start" value="Start" />
      <input type="button" id="stop" value="Stop" />
    </fieldset>
</body>
<script type="text/javascript">

var sample = function(args,child)
{
  // private vars
  args = args || {wait:10000,msg:'ping!'};
  var wait = args.wait || 10000;
  var msg = args.msg || 'ping!';
  var timer_ping = null;

  // private methods
  function init()
  {
    document.getElementById('start').onclick = start;
    document.getElementById('stop').onclick = stop;
    start();
    ping();
  }
  
  function start()
  {
    timer_ping = setInterval(ping,wait);
    document.getElementById('status').innerHTML = 'Running...';
  }
  
  function stop()
  {
    clearInterval(timer_ping);
    document.getElementById('status').innerHTML = 'Stopped';
  }
  
  function ping()
  {
    var dt = new Date();
    alert(msg+'\n'+dt);
  }

  // call internal init
  init();
  
  // public interface
  var that = {};
  that.init = init;
  that.start = start;
  that.stop = stop;
  
  return that;
  
};

var s = null;

window.onload = function()
{
  s = sample();
}

</script>
</html>

code