@simbolco/class-utils v1.0.1
Class Utilities Library
An ECMAScript 5+ library which provides utilities for classes or class-like functions. TypeScript support is provided out of the box.
This library is web, CommonJS, and RequireJS compatible. In web browsers, the
global variable classUtils
contains this library's exports.
The code which this library consists of is licensed under the Mozilla Public License version 2.0. This means that this code can be reused and integrated into other projects so long as the following conditions are satisfied:
- The source code pertaining to this library must be publically accessible and available when distributed.
- A copy of the license and copyright notice must be included with the library.
- Any modifications to this library must be released under the Mozilla Public License version 2.0 or a sufficiently similar license when distributing it.
Basic Usage
restrict
The restrict
function restricts all configurable instance getters, setters,
and methods of a given class to only being able to be called by instances said
class. restrict
additionally sets all non-configurable static and method
properties of a class to be non-configurable and non-enumerable. Data properties
are further set as non-writable and, finally, the class is given a
Symbol.toStringTag
which matches the name
property of the constructor.
import { restrict } from '@simbolco/class-utils';
class A_Class {
get x() {
// ...
}
y() {
// ...
}
// if static blocks are supported:
static {
restrict(this);
}
}
// if static blocks aren't supported:
restrict(A_Class);
A_Class.prototype.x; // throws a TypeError
A_Class.prototype.y.call(new Date); // throws a TypeError
A_Class.prototype.x = function() {
// ...
}; // fails
sealed
The sealed
function prevents further extension of the static or instance
properties and methods of a class using Object.seal
.
import { sealed } from '@simbolco/class-utils';
class SomeClass {
// ...
// if static blocks are supported:
static {
sealed(this);
}
}
SomeClass.new_property = 1; // fails
isConstructor
The isConstructor
function duck types whether a given function is a
constructor.
import { isConstructor } from '@simbolco/class-utils';
class AnotherClass {
// ...
}
isConstructor(AnotherClass); //> true
isConstructor(String); //> true
isConstructor("a string"); //> false
isConstructor(Array.prototype.indexOf); //> false
isConstructor(() => "arrow function"); //> false
isConstructor(function() { //> true !!
return "classic function";
});
propertiesOf
The propertiesOf
function returns an iterator over a given object's own keys
and property descriptors. The keys includes both strings and symbols.
This is provided as an ease of implementing your own class decorators or utility functions.
import { propertiesOf } from '@simbolco/class-utils';
for (const [key, descriptor] of propertiesOf(AnotherClass.prototype)) {
// process the descriptor...
}
Advanced Usage
Decorators
In TypeScript with the experimental decorators extension enabled or JavaScript
implementations which support the TC-39 class decorators proposal, the restrict
and sealed
functions can be used as decorators:
@sealed @restrict class LockedDown {
// ...
}
Excluding properties from being restricted
The restrict
function takes an optional options parameter in both its
functional and decorator forms. With it, one can specify static and instance
property keys which the implementor would prefer to not have restricted or
otherwise set as non-configurable, non-enumerable, and non-writable.
const FunctionalOptions = restrict(class {
// ...
}, {
exclude: ['propD', 'propE'],
excludeStatic: [Symbol.toStringTag]
});
@restrict({
exclude: ['propA', 'propB'],
excludeStatic: ['propC']
}) class DecoratorOptions {
static propC = 1;
static propD = 2;
// ...
}
DecoratorOptions.propC = 3; // succeeds
DecoratorOptions.propD = 4; // fails
DecoratorOptions.propC; //> 3
DecoratorOptions.propD; //> 2
Classes which have already been passed into restrict
cannot be restrict
ed
again, thus static or instance excludes can only be provided once.
Custom @@toStringTag
name
A custom Symbol.toStringTag
string can be passed as an option to restrict
via the name
property of the options parameter:
@restrict({ name: "Y" }) class X {}
Object.prototype.toString.call(new X) //> "[object Y]"
Programming Interface
isConstructor
Parameters
- obj - An object.
Returns
True if obj duck types to a constructor (i.e. its typeof
is "function
" and
has its own prototype
property). False otherwise.
propertiesOf
Parameters
- obj - An object.
Returns
An iterator of a obj's own property keys and descriptors as a read-only array.
restrict
A decorator which performs the following actions on all configurable properties of a given constructor and its prototype that are not explicitly marked in the options parameter as excluded:
- Sets the property to be non-configurable.
- Sets the property to be non-enumerable.
- If the property is a data property, it is set to be non-writable.
In addition to the above steps, the following actions are performed on all
configurable properties of a given constructor's prototype, except for the
constructor
property:
- If the property is a getter/setter property, the get and set functions are restricted to only allowing calls from class instances.
- If the property is a data property corresponding to a function, the property is restricted to only allowing calls from class instances.
If the provided constructor does not already have its own a Symbol.toStringTag
property defined, this function will provide one corresponding to either the
name
field of the options parameter or the name
property of the provided
constructor.
Parameters
- iface - A constructor to restrict the methods, getters, and setters of.
- options - (optional) Property keys to not apply restrictions to and/or the name tag to provide to iface.
Returns
The iface parameter.
sealed
A decorator which seals a provided constructor and its prototype, preventing extension, modification, or tampering of their properties.
Parameters
- iface - A constructor to seal.
Returns
The iface parameter.