DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Jason has posted 22 posts at DZone. View Full User Profile

Basic Unified JavaScript Class Syntax

06.17.2009
| 1904 views |
  • submit to reddit
        Example showing basic object-oriented JavaScript with public and private members. Various conventions are used to extend the object and its prototype.

The use of the "me" variable inside the constructor function unifies the two common methods of class definition: the simple-but-inefficient instance-based and the efficient-but-clumsy prototype-based.

var buffer = [];
function println(s) { buffer.push(s + "\r\n"); }
function flush() { alert(buffer.join("")); }

function Foo()
{
  var me = this.constructor.prototype;

  var privateA = 1;
  function privateB () { ++privateA; println("privateB();"); };

  this.instanceA = 1;

  me.publicA = function () { println("publicA();"); };
  me.publicB = function () { println("publicB(); privateA=" + privateA); };
  me.publicC = function () { privateB(); println("publicC(); privateA=" + privateA); };

  this.publicZ = function () { println("publicZ();"); };
}

Foo.prototype.publicD = function () { println("publicD();"); };

var a = new Foo();
a.publicA();
a.publicB();
a.publicC();
a.publicD();
a.publicZ();
println("a.privateA=" + a.privateA);
try { a.privateB(); } catch (e) { println("a.privateB()=" + e.message); }
var b = new Foo();
b.publicA();
b.publicB();
b.publicC();
b.publicD();
b.publicZ();
println("b.privateA=" + b.privateA);
try { b.privateB(); } catch (e) { println("b.privateB()=" + e.message); }

Foo.prototype.publicD = function () { println("publicD2();"); };
Foo.prototype.publicZ = function () { println("publicZ2();"); };

a.publicD();
b.publicD();
a.publicZ();
b.publicZ();

flush();

/* OUTPUT:
publicA();
publicB(); privateA=1
privateB();
publicC(); privateA=2
publicD();
publicZ();
a.privateA=undefined
a.privateB()=Object doesn't support this property or method
publicA();
publicB(); privateA=1
privateB();
publicC(); privateA=2
publicD();
publicZ();
b.privateA=undefined
b.privateB()=Object doesn't support this property or method
publicD2();
publicD2();
publicZ();
publicZ();
*/


A more practical and optimized class template might look like this:
function Foo ()
{
  /* Initialize Instance Members */
  this.instanceA = 1;
  this.instanceB = function () { return this.instanceA; };

  var privateA = 2;
  function privateB () { return privateA; };

  /* Initialize the Class Prototype */
  if (this.__protoInitialized) { return; };
  var proto = this.constructor.prototype;
  proto.__protoInitialized = true;

  proto.privilegedA = function () { return privateB(); };

  proto.publicA = function () { return "publicA();"; };
  proto.publicB = function () { return this.publicA() + " publicB();"; };
}