Part of our (corporate) product is a Javascript API, we often hand copies of our (class) objects around and only want specific attributes exposed. Masquerade JS is a wrapper that attempts to correctly scope class methods and storage in OO Javascript. It allows you to expose only what you want to expose. There is a small caveat, if you pass references to the private this you will expose the entire object. If you want to stay protected only pass a reference to the public object provided to you on creation. The public object is briefly made available within the constructor on this.$public, be careful of circular references if you use it.
This adds class functionality to ES5, similar but not identical to ES6. However it adds private scoping to fields and methods which is not available in ES5 or ES6.
varExample=newClass({construct:
function(){this.count=0;this.string='example string';}});varexample=newExample();getString will be publicly callable.
varExample=newClass({construct:
function(){this.count=0;this.string='example string';},getString:
function(){returnthis.string;}});varexample=newExample();example.getString();/* returns 'example string' */_incrementCount is only callable from the this context.
varExample=newClass({construct:
function(){this.count=0;this.string='example string';},getString:
function(){this._incrementCount();returnthis.string;},_incrementCount:
function(){this.count++;}});varexample=newExample();example._incrementCount();/* undefined */example.getString()/* returns 'example string' and increments this.count */getDate is copied by reference to the class definition.
varExample=newClass({construct:
function(){this.count=0;this.string='example string';},$getDate:
function(){return(newDate()).getTime();}});Example.getDate();/* returns epoch */Extend will inherit all methods from Example.
varExtend=Example.extend({construct:
function(){this.count=0;this.string='extend string';}});varextend=newExtend();extend.getString()/* returns 'extend string' and increments this.count */getStringCount will only be available on instances of Extend.
varExtend=Example.extend({construct:
function(){this.count=0;this.string='extend string';},getStringCount:
function(){returnthis.string+' '+this.count;}});varexample=newExample();example.getStringCount();/* undefined */varextend=newExtend();extend.getStringCount();/* returns 'extend string *this.count' */Anything stored on this will be private to an instance.
varExample=newClass({construct:
function(){this.count=0;this.string='example string';}});varexample=newExample();example.count;/* undefined */classPublic is copied by reference to the class definition and class instances.
varExample=newClass({classPublic:
{string: 'class public'},construct:
function(){this.count=0;this.string='example string';}});varexample=newExample();example.classPublic.string;/* 'class public' */Example.classPublic.string;/* 'class public' */classStatic is copied by reference to the class definition.
varExample=newClass({$classStatic:
{string: 'class static'},construct:
function(){this.count=0;this.string='example string';}});varexample=newExample();example.classStatic.string;/* undefined */Example.classStatic.string;/* 'class static' */_classPrivate is copied by reference to class instances.
varExample=newClass({_classPrivate:
{string: 'class private'},construct:
function(){this.count=0;this.string='example string';}getClassPrivate:
function(){returnthis._classPrivate.string;}});varexample=newExample();varextend=newExtend();example.classPublic.string;/* undefined */Example.classPublic.string;/* undefined */example.getClassPrivate();/* returns 'class private' */extend.getClassPrivate();/* returns 'class private' */string becomes a property on class instances.
varExample=newClass({construct:
function(){this.count=0;this.string='example string';},defineProperties:
{string:
{get:
function(){returnthis.string;}}}});varexample=newExample();example.string;/* 'example string' */The this referred to inside class functions is not the same as the constructed class object, but is an instance of the same class.
varExample=newClass({construct:
function(){this.count=0;this.string='example string';},getThis:
function(){returnthis;}});varexample=newExample();varprivateExample=example.getThis();example===privateExample/* false */exampleinstanceofExample/* true */privateExampleinstanceofExample/* true */Class data storage will copy by reference during a Class.extend() if it is an object, but not if it is a scalar.
varExample=newClass({scalar: '1234',obj: {value: 1234},obj2: {value: 5678}});varsubClass=Example.extend({});varexample=newExample();varsub=newsubClass();sub.scalar='abcd';/* Updates only the subclass */example.scalar==='1234'/* true */sub.obj.value=0;/* Updates by-reference */example.obj.value===0;/* true */sub.obj2='replace';/* Replace by-reference copy */example.obj2;/* `{value: 5678}` */