Control Class is a Java-like access control ponyfill for ES6 (JavaScript) classes. This essentially allows you to use keywords like public, private, static, and final without polluting the global scope.
This is made possible by various features of ES6/ES2015 such as the spread/rest operator, WeakMaps, and class syntax. It therefore requires Node.js 6.5.0 or later to function properly. Transpilation to ES5 may also be possible with a WeakMap polyfill.
Please note that this is an experimental proof of concept. This should not be used in any production environment. Also, private variables are currently visible to subclasses, this will be fixed once support for both private and protected variables are added in a future update.
$ npm install control-class
Import or require Control Class in each module you want to declare a controlled class.
const ControlClass = require('control-class')
Create a new instance of Control Class. The Control Class constructor takes two parameters: variable delcarations (required) and options (optional). Creating this class will return an object with three important functions and classes: $_, BaseClass, and extendable. See examples below for details on how to use them.
let { $_, BaseClass, extendable } = new ControlClass(declarations, options)
When declaring your class, extend BaseClass regardless of whether or not you are actually extending any super class.
class MyClass extends BaseClass {
constructor(arg) {
super()
}
}
You can access all declared variables within the class by wrapping 'this' with the '$_' function. '$_(this)' is only required for private variables; public variables can be accessed with both '$_(this)' and 'this'.
$_(this).var = 'value'
If you want to make the class extendable, export the class after passing it through the extendable() function. You are expected to use one class per Node module (JS file), similar to Java classes.
module.exports = extendable(Person)
When creating a new Control Class, the first parameter is the variable declaration. The declaration is expected to be an object; the most common implementation is shown below (see examples for other methods).
{
varName: {
value: 'YOUR_DEFAULT_VALUE',
public: true,
static: false,
final: false
},
[...]
}
Attribute | Default |
---|---|
value | none [required] |
public | true |
static | false |
final | false |
Control Class has a second optional parameter, used for passing an options object.
Option | Description |
---|---|
extends | Reference to the class you are extending |
Before declaring your class, you must first create a new Control Class. You declare all variables here, much like the beginning of a Java class, or a header file in C.
const ControlClass = require('control-class')
let { $_, BaseClass, extendable } = new ControlClass({
public: {
nickname: {
value: 'Joe',
static: false,
final: false
}
},
private: {
firstName: {
value: 'John',
static: false,
final: false
},
lastName: {
value: 'Hancock',
static: false,
final: false
}
}
})
You may also use shorthand to declare variables. Control Class will assume they are both mutable (non-final) and instanced (non-static).
const ControlClass = require('control-class')
let { $_, BaseClass, extendable } = new ControlClass({
public: {
nickname: 'Joe'
},
private: {
firstName: 'John',
lastName: 'Hancock',
species: {
value: 'human',
static: true,
final: true
}
}
})
If you prefer, you may also specify whether a variable is public within each variable declaration. However, you may not use shorthand syntax this way.
const ControlClass = require('control-class')
let { $_, BaseClass, extendable } = new ControlClass({
nickname: {
value: 'Joe',
public: true,
static: false,
final: false
},
firstName: {
value: 'John',
public: false,
static: false,
final: false
},
lastName: {
value: 'Hancock',
public: false,
static: false,
final: false
}
})
Creating a new Control Class returns an object with three attributes: $_, BaseClass, and extendable. You will need these to use Control Class with any class you declare.
class Person extends BaseClass {
constructor(firstName, lastName, nickname) {
super()
if (firstName) $_(this).firstName = firstName
if (lastName) $_(this).lastName = lastName
if (nickname) $_(this).nickname = nickname
}
get name() {
return $_(this).firstName+' '+$_(this).lastName
}
}
module.exports = extendable(Person)
You may extend a class that uses Control Class by requiring the class you want to extend, and pass it as the 'extends' option after your variable declarations. You still extend 'BaseClass' when you declare your new subclass. If you use a constructor you must use super() to call the super class constructor.
const ControlClass = require('control-class')
const Person = require('./Person.js')
let { $_, BaseClass, extendable } = new ControlClass({
favoriteLanguage: {
value: null,
public: false,
static: false,
final: false
}
}, { extends: Person })
class Developer extends BaseClass {
constructor(firstName, lastName, nickname, favoriteLanguage) {
super(firstName, lastName, nickname)
$_(this).favoriteLanguage = favoriteLanguage
}
get favoriteLanguage() {
return $_(this).favoriteLanguage
}
set favoriteLanguage(favoriteLanguage) {
$_(this).favoriteLanguage = favoriteLanguage
}
}
module.exports = extendable(Developer)
Control Class was created by Harry Hanssen