Class: decl

(abstract) barejs.decl()

Module for declaring classes, interfaces, enums, and checking implementations. decl uses the inheritance natively supported by JavaScript, instead of trying to emulate multiple inheritance or providing "super" or "base" keyword emulation. This combined with the fact that decl doesn't generate a constructor function (the defining code has to supply it) leads to classes with no run-time overhead. It also means there is no "magic" performed. Implementors using decl's inheritance are responsible for calling the base class constructor and methods using the standard JavaScript call mechanism:

 function A( _name )
 {
     this.name = _name;
 }

 decl.declareClass( A,
 {
     toString: function()
     {
         return this.name;
     }
 }

 function B( _name, _age )
 {
     // Invoke base class constructor on this object
     A.call( this, _name );
     this.age = _age;
 }

 decl.declareClass( B, A,
 {
     toString: function()
     {
         // Invoke A::toString() and append our age to it.
         return A.prototype.toString.call( this ) + "; age " + this.age;
     }
 } );

In the debug version of barejs, decl adds a lot of metadata to provide a great debugging experience. When defined with named constructors, objects created with decl will be highly discoverable and debuggable in browsers like Chrome.

Constructor

(abstract) new decl()

Note: decl is not a constructor; call its static members.

Source:

Classes

Enum
Interface
SpecialType

Members

(static) hasPropertySupport :boolean

This convenience property is true if the environment supports property getters and setters.

Type:
  • boolean
Source:

(static, readonly) readOnlyProperty :object

Convenience property to ease defining a read only property on an Interface. It as simply a shortcut for '{ allowGet: true, allowSet: false }':

 decl.declareInterface( function MyInterface() {},
 {
     // The following two definitions have exactly the same effect:
     myProperty: decl.readOnlyProperty,
     myProperty: { allowGet: true, allowSet: false }
 } );
Type:
  • object
Source:

(static, readonly) readWriteProperty :object

Convenience property to ease defining a read/write property on an Interface. It as simply a shortcut for '{ allowGet: true, allowSet: true }':

 decl.declareInterface( function MyInterface() {},
 {
     // The following two definitions have exactly the same effect:
     myProperty: decl.readWriteProperty,
     myProperty: { allowGet: true, allowSet: true }
 } );
Type:
  • object
Source:

Methods

(static) abstractClass(_class, _baseopt, …_interfaceopt, _staticopt, _prototypeopt) → {function}

Declare a constructor function to be an abstract class. Allows specifying an optional base class and interfaces implemented. When reading or writing decl.abstractClass statements, it might help to know it was designed to mimic popular languages in its format. Here's an example:

 // With common languages
 abstract class ClassName : BaseClass, Interface1, Interface2 // C#
 abstract class ClassName extends BaseClass implements Interface1, Interface2 // Java
 {
     private String _name;

     public ClassName( _name )
     {
         super( 42 );
         this._name = _name;
     }

     public String toString()
     {
         return this._name;
     }
 }

 // With barejs.decl:

 function ClassName( _name )
 {
     BaseClass.call( this, 42 );
     this._name = _name;
 }

 decl.abstractClass( ClassName, BaseClass, Interface1, Interface2,
 {
     // This puts the _name property as null on the prototype,
     // which is purely for clarity (e.g. stating it exists).
     _name: null,

     toString: function()
     {
         return this._name;
     }
 }
  • If a base class is provided, decl will ensure _class.prototype is instanceof _base.prototype.
  • For abstract classes, decl will not validate if interface methods are implemented.
  • If a _static argument is specified, it will be applied to the constructor function using defineObject.
  • If a _prototype argument is specified, it will be applied to the prototype using defineObject.
  • If only 1 object is supplied, it is always interpreted as prototype definition, never as static. You must specify null for the prototype object if you only want to specify static members.

By default, any static members (except name, prototype, constructor, superclass and other metadata) will inherit. A class can make static functions "private" by defining a static $private function, accepting a String/Symbol as key. This function should return true for any keys that should not inherit. The $private function itself will never inherit.

Parameters:
Name Type Attributes Description
_class function

The constructor function of the class

_base function <optional>

Optional: Extended base class

_interface function <optional>
<repeatable>

Optional: Any number of implemented interfaces

_static object <optional>

Optional: static definition; properties that will be added to the constructor function.

_prototype object <optional>

Optional: prototype definition: properties that will be added to the prototype

Source:
Returns:

The constructor function (_class), so it can immediately be returned

Type
function

(static) asFunctional(_target, _functionalInterface, _strictopt)

Interpret _target as implementing a Java Functional Interface. A functional interface is an Interface with exactly 1 function defined. Java allows lambda expressions to be generated for arguments of this type of interface. This method allows normalizing a function or object to a "Functional Interface Object", so Java behavior can be emulated. This function will accept:

  • null/undefined (then null is returned)
  • A function (an 'instance' of _functionalInterface is returned, with this function in place).
  • An object complying with _functionalInterface

Any other argument will throw a TypeError.

Parameters:
Name Type Attributes Default Description
_target object | function

The target object or function.

_functionalInterface function

The interface to use as functional interface. May only have a single method defined.

_strict boolean <optional>
false

Optional: set to true to avoid a duck-type check, and only check decl metadata for interfaces implemented.

Source:
Throws:

A TypeError may occur if _functionalInterface is not a valid functional interface, or if _target does not comply with the interface.

Type
TypeError
Returns:

Either an object compliant with _functionalInterface, or null.

(static) declareClass(_class, _baseopt, …_interfaceopt, _staticopt, _prototypeopt) → {function}

Declare a constructor function to be a class. Allows specifying an optional base class and interfaces implemented. When reading or writing decl.declareClass statements, it might help to know it was designed to mimic popular languages in its format. Here's an example:

 // With common languages
 class ClassName : BaseClass, Interface1, Interface2 // C#
 class ClassName extends BaseClass implements Interface1, Interface2 // Java
 {
     private String _name;

     public ClassName( _name )
     {
         super( 42 );
         this._name = _name;
     }

     public String toString()
     {
         return this._name;
     }
 }

 // With barejs.decl:

 function ClassName( _name )
 {
     BaseClass.call( this, 42 );
     this._name = _name;
 }

 decl.declareClass( ClassName, BaseClass, Interface1, Interface2,
 {
     // This puts the _name property as null on the prototype,
     // which is purely for clarity (e.g. stating it exists).
     _name: null,

     toString: function()
     {
         return this._name;
     }
 }
  • If a base class is provided, decl will ensure _class.prototype is instanceof _base.prototype.
  • If interfaces are declared, decl will validate methods are implemented.
  • If a _static argument is specified, it will be applied to the constructor function using defineObject.
  • If a _prototype argument is specified, it will be applied to the prototype using defineObject.
  • If only 1 object is supplied, it is always interpreted as prototype definition, never as static. You must specify null for the prototype object if you only want to specify static members.

By default, any static members (except name, prototype, constructor, superclass and other metadata) will inherit. A class can make static functions "private" by defining a static $private function, accepting a String/Symbol as key. This function should return true for any keys that should not inherit. The $private function itself will never inherit.

Parameters:
Name Type Attributes Description
_class function

The constructor function of the class

_base function <optional>

Optional: Extended base class

_interface function <optional>
<repeatable>

Optional: Any number of implemented interfaces

_static object <optional>

Optional: static definition; properties that will be added to the constructor function.

_prototype object <optional>

Optional: prototype definition: properties that will be added to the prototype

Source:
Returns:

The constructor function (_class), so it can immediately be returned

Type
function

(static) declareEnum(_class, _prototypeopt) → {object}

Declare an enum. decl will make _class derive from the special internal Enum type, and return a new instance of it. Enum values should be set on 'this' in the constructor, utility methods should be added to the prototype.

 var SampleEnum = decl.declareEnum( function SampleEnum()
 {
     this.Bit1 = 1;
     this.Bit2 = 2;
     this.Bit3 = 4;
     this.Bit4 = 8;
 },
 // End of constructor, what follows is the prototype definition:
 {
     hasBit: function( _bit, _value )
     {
         // hasValue is provided by the Enum base class
         if ( !this.hasValue( _bit ) )
             throw new TypeError( "Unknown SampleEnum value: " + _bit );
         return _value & _bit === _bit
     }
 } );

 // SampleEnum is now instanceof the SampleEnum function passed to decl.
 SampleEnum.hasBit( SampleEnum.Bit2, 3 ); // true
 // And it inherited decl's Enum type members
 SampleEnum.names(); // ["Bit1", "Bit2", "Bit3", "Bit4"]
 SampleEnum instanceof Object; // false

Note that the prototype property, if specified, is applied using defineObject.

Parameters:
Name Type Attributes Description
_class function

The "constructor" function to declare as an Enum.

_prototype object <optional>

Optional: things to add to the enum prototype.

Source:
Returns:

The enum instance (instanceof _class).

Type
object

(static) declareInterface(_class, …_interfaceopt, _staticopt, _prototypeopt) → {function}

Declare an interface. An interface can extend multiple interfaces by passing them as additional parameters. The constructor function _class will be made to derive from the special internal Interface type. It is not meant to be instantiated, and decl will never call the interface's constructor.

Parameters:
Name Type Attributes Description
_class function

The "constructor" function to declare as an interface.

_interface function <optional>
<repeatable>

Any number of interfaces to extend.

_static object <optional>

Optional: static definition; properties that will be added to the constructor function.

_prototype object <optional>

Optional: prototype to apply

Source:
Returns:

The interface definition (_class).

Type
function

(static) defineObject(_target, _definition, _objectNameopt)

defineObject is similar to decl.defineProperties, but it expands the _definition's properties if needed. It will update values of properties that are not property assigment definitions to be proper property definitions, defaulting to:

 { configurable: false, writable: true, enumerable: true, value: <value> }

(Note: enumerable will be false if the name starts with _ or is a Symbol). defineObject will iterate the _definition object and expand properties on it. Please be aware of the following:

  1. _destination will be modified. If that's a problem, use Object.assign to create a copy first.
  2. Existing properties are scanned for presence of a value, get or set property. If these are present on a value, you must use the full property syntax:

    decl.defineObject( MyClass,
    {
        // Since the object we want to assign to the MyClass constructor function has properties that make it look like
        // a property definition, we have to wrap it in a property definition as required by Object.defineProperties.
        staticFlags: { enumerable: true, value: { get: true, set: false } }
    } );
  3. defineObject will silently ignore getter/setter properties in environments that don't support them, unlike module:barejs.decl.defineProperties.

  4. You can reference a getter or setter by name, provided it is also on the definition object:

    decl.defineObject( {},
    {
        // underlying data Array, not enumerable, configurable or writable
        _values: { value: [] },
        // getSize function that returns the length of the _values
        getSize: function() { return this._values.length; },
        // Size property. Refers to the getSize function for the getter, instead of using an inline function.
        size: { enumerable: true, get: "getSize" }
    } );
Parameters:
Name Type Attributes Description
_target object

The target object

_definition object

The definitions to assign to _target. Note that _definition will be modified to contain property definitions(!).

_objectName string <optional>

Optional: the name of the object. If passed, decl will generate displayName properties on methods for an enhanced debugging experience. For example: if "decl" is passed as name, and there's an "is" function on _definition, the displayName of the "is" function will be set to "decl.is").

Source:
Returns:

_target The target object, expanded

(static) defineProperties(_target, _definitions) → {object}

decl re-exports Object.defineProperties.

If the native version is not available, a fall-back is used. The fallback supports the same syntax as the original, and uses the defineProperty fallback.

Parameters:
Name Type Description
_target object

The object to define the property on

_definitions object

Object containing properties, each of which have a value that is a definition as passed to defineProperty.

Source:
Returns:

The object the properties where defined on (_target).

Type
object

(static) defineProperty(_target, _key, _definition) → {object}

decl re-exports Object.defineProperty.

If the native version is not available, a fall-back is used. The fallback supports the same syntax as the original, but falls back to simple assignment or deprecated constructs like __defineGetter__. Be aware that property getters or setters may not be supported in some environments, which is indicated by hasPropertySupport being false.

Parameters:
Name Type Description
_target object

The object to define the property on

_key string | Symbol

The name or Symbol to set

_definition object

Object containing either a value property, or a get and/or set property (function).

Properties
Name Type Attributes Default Description
get function <optional>

A getter function, taking no arguments and returning the property value.

set function <optional>

A setter function, taking a value as argument.

value * <optional>

The value to assign to the property.

writable boolean <optional>
false

(Only in combination with value) Whether assigning to the property is allowed. For properties with get/set, the writable is implicit (by absence or presence of a setter function).

configurable boolean <optional>
false

Whether the property may be altered via delete or a next defineProperty call.

enumerable boolean <optional>
false

Whether the property shows up in object property enumerations.

Source:
Returns:

The object the properties where defined on (_target).

Type
object

(static) freeze(_target) → {object}

decl re-exports Object.freeze. A frozen object may not be altered in any way. No properties may be added or removed (like seal), and all values are made read-only.

If the native version is not available, a no-operation function is used. The object is not altered in any way and simply returned.

Parameters:
Name Type Description
_target object

The object to freeze.

Source:
Returns:

The object that was passed (_target).

Type
object

(static) hasBase(_class, _base) → {boolean}

Checks if _class has _base as a superclass. Also true if _class === _base. Do not use this method to check if an Object is of a specific type, use the instanceof operator for that instead.

Parameters:
Name Type Description
_class function

The function to check.

_base function

The base class to check for.

Source:
Returns:

True if the class has the base class, false otherwise.

Type
boolean

(static) hasInterface(_target, _interface, _strictopt) → {boolean}

Checks if _target (or a base class) implements the specified Interface. Works on both instances and the class constructor.

Parameters:
Name Type Attributes Default Description
_target object | function

The object or class constructor to check.

_interface function

The interface to check for. If interface is not a valid interface, this method always returns false.

_strict boolean <optional>
false

Optional: set to true to avoid a duck-type check, and only check decl metadata for interfaces implemented.

Source:
Returns:

True if _target (or a base class) implements the interface, false otherwise.

Type
boolean

(static) is(_a, _b) → {boolean}

Wrapper for Object.is that will "unproxy" values.

 // This returns false, Object.is sees two different objects:
 Object.is( instance, instance.as( MyInterface );

 // This returns true, decl will unproxy proxies.
 decl.is( instance, instance.as( MyInterface ) );
Parameters:
Name Type Description
_a

Any value to check for equality

_b

Any value to check for equality

Source:
Returns:

True if the values are considered equal, false otherwise.

Type
boolean

(static) isEnum(_target) → {boolean}

Check if the _target is an enum. Only works with instances, since enums should not expose their class constructor directly.

Parameters:
Name Type Description
_target object

The instance to test if it is an enum.

Source:
Returns:

True if _target is an enum, false otherwise.

Type
boolean

(static) isFrozen(_target) → {boolean}

decl re-exports Object.isFrozen.

If the native version is not available, a no-operation function is used. The object is not altered by the fallback, and it always returns false (since freezing objects is not supported).

Parameters:
Name Type Description
_target object

The object to evaluate.

Source:
Returns:

True if the object (_target) is frozen, false otherwise. The fallback always returns false.

Type
boolean

(static) isInterface(_target) → {boolean}

Check if the _target is an interface. Only works with class constructors, since there should be no instance of an interface.

Parameters:
Name Type Description
_target function

The class constructor to test if it is an interface.

Source:
Returns:

True if _target is an interface, false otherwise.

Type
boolean

(static) isProxy(_target) → {boolean}

Check if the target is a proxy object.

Parameters:
Name Type Description
_target object

The object to check.

Source:
Returns:

True if _target is a proxy object, false otherwise.

Type
boolean

(static) isSealed(_target) → {boolean}

decl re-exports Object.isSealed. A sealed object may not be altered by adding or removing properties. Existing properties may be altered (provided they are writable).

If the native version is not available, a no-operation function is used. The object is not altered by the fallback, and it always returns false (since sealing objects is not supported).

Parameters:
Name Type Description
_target object

The object to evaluate.

Source:
Returns:

True if the object (_target) is sealed, false otherwise. The fallback always returns false.

Type
boolean

(static) preventCast(_class) → {Symbol}

Tells the proxy system casting to this type is not allowed. Should only be used for very low level classes, otherwise performance will be impacted.

Parameters:
Name Type Description
_class function

The type to disallow casting to

Source:
Returns:

Key to cast to this type. NEVER export this key in any way.

Type
Symbol

(static) proxy(_target, _interface) → {object}

Create and return a proxy object for the target

Parameters:
Name Type Description
_target object

The object to proxy

_interface function

The interface defining the members to proxy.

Source:
Returns:

The proxy object (instanceof _interface).

Type
object

(static) seal(_target) → {object}

decl re-exports Object.seal.

If the native version is not available, a no-operation function is used. The object is not altered in any way and simply returned.

Parameters:
Name Type Description
_target object

The object to seal.

Source:
Returns:

The object that was passed (_target).

Type
object