OOP JavaScript Thing()

Thing.js

// =============================================================================
//  OOP JavaScript Thing() 
//    Encapsulate a unique ID along with an associative array of attributes
//  Author:
//    Kevin J. Crosby (SkewsMe.com)
//
//  Includes:
//    Dean Edwards: A Base Class for JavaScript Inheritance
//      http://dean.edwards.name/weblog/2006/03/base/
//    Optional Function Arguments in JavaScript
//      http://www.openjs.com/articles/optional_function_arguments.php
//    Unique ID generator without a global temp variable
//      http://snipplr.com/view/2574/unique-id-generator-without-a-global-temp-variable/
// =============================================================================
if (typeof Base == 'undefined') alert ("Base.js class undefined");

// Unique ID number generator
var skewsme_ThingMakeUniqueId = (function(){var id=0;return function(){return id++;}})();

var Thing = Base.extend({ // Create an associative array of attributes with a unique ID 
    constructor: function(/* associative array of default attribues */){
      var attr = arguments[0];
      this._attributes = ((typeof attr != 'undefined') ? attr : {});
      this._uid = skewsme_ThingMakeUniqueId();
    },

    getAttribute: function(label){ // Return the value of an attribute from a Thing
      return this._attributes[label];
    },

    setAttribute: function(label, value){ // Set and return the value of an attribute from a Thing
      return this._attributes[label] = value;
    },

    mungeAttributes: function(attr){ // Add/Set associative array of attributes of a Thing
      for (var label in this._attributes){
        if (typeof attr[label] == 'undefined'){
          attr[label] = this._attributes[label];
        }
      }
      this._attributes = attr;
    },

    getUniqueId: function() { return this._uid; }, // Returns the unique ID of a Thing 
    
    toString: function(){ // Return CSV list of attibutes beginning with the unique ID number
      var str = 'uid:' + this._uid;
      for (var label in this._attributes){
        str += ',' + label + ':' + this._attributes[label];
      }
      return str;
    },

    forEach: function(fun /*, thisp*/){
      if (typeof fun != 'function'){
        throw new TypeError("Thing.forEach(function(self, element, label, Thing){}, [thisp])
expected function but received " + typeof fun);
      }
      var thisp = arguments[1];
      for (var label in this._attributes){
        fun.call(thisp, this._attributes[label], label, this); // fun(thisp,element,label,Thing)
      }
    }

});

Example

var ClientItem = Thing.extend({
    constructor: function(name){
      // initialize default values
      this.base({ 'name':name, 'attack':0, 'defense':0, 'price':0, 'trade':false });
      var attr = arguments[1]; // optionally change any values
      if (typeof attr != 'undefined'){
        this.mungeAttributes(attr);
      }
    }
});

var Weapon = ClientItem.extend({
    constructor: function(name){
      this.base(name, { 'attack':1, 'trade':true });
      var attr = arguments[1];
      if (typeof attr != 'undefined'){
        this.mungeAttributes(attr);
      }
    }
});

var Shield = ClientItem.extend({
    constructor: function(name){
      this.base(name, { 'defense':1, 'trade':true });
      var attr = arguments[1];
      if (typeof attr != 'undefined'){
        this.mungeAttributes(attr);
      }
    }
});

item = new Weapon("Knife", { 'attack':2, 'price':1, 'trade':true });
alert(item.toString());

Leave a Reply

Stop censorship