class4js

The class4js module is for class-driven development in JavaScript. It allows to emulate classes in JavaScript. Module is based on ECMAScript 5 standart and implements open/close principle: 'A module should be open for extension but closed for modifications'

npm install class4js
55 downloads in the last week
110 downloads in the last month

class4js

http://www.class4js.com

The class4js module is for class-driven development in JavaScript. It allows to emulate classes in JavaScript. Module based on ECMAScript 5 standart and implements open/close principle: "When class is created, class is closed for modifications". class4js is free software distributed under the terms of the GNU General Public License version 3 and can be used with node.js, modern web browsers and even with PhantomJS.

// Simple class example:

var Shape = $class({
  __construct__: function () {
    this.__x = 0;
    this.__y = 0;
  },
  x: {
    get: function () {
      return this.__x;
    },
    set: function (value) {
      this.__x = value;
    }
  },
  y: {
    get: function () {
      return this.__y;
    },
    set: function (value) {
      this.__y = value;
    }
  },
  draw: function () {
    console.log("Drawing shape at: (" + this.x + ", " + this.y + ")");
  }, 
  moveTo: function (x, y) {
    this.x = x;
    this.y = y;
  }
});

var shape = new Shape({ x: 100, y: 100 });
shape.moveTo(120, 85);
shape.draw();

// Output:
// Drawing shape at: (120, 85)

Overview

  • Installation
    • Node.js
    • Web Browser
    • PhantomJS
  • API
    • Class
      • Constructor
      • Static Constructor
      • Object initializer
      • Constant
      • Fields
      • Properties
      • Static Members
      • Inheritance
    • Abstract Class
    • Static Class
    • Enum
    • Interface
    • Object Factory
    • Modules
    • Namespace
    • Extensions
  • License

Installation

Node.js

To install class4js module for node.js, this command should be used:

npm install class4js

Also class4js module's loading statement should be added to main module:

'use strict';

require('class4js');

// Your code goes here...

Web Browser

To use class4js module in web browser, simply download newest minified class4js module file and include it to your browsers. You can also define main module of application:

<!DOCTYPE HTML>
<html>
<head>
  <script src="./scripts/class4js.min.js" data-main="./scripts/main.js"></script>
</head>
<body>
  <!-- Your code goes here... -->
</body>
</html>

PhantomJS

To use class4js in with PhantomJS, simply copy class4js module near PhantomJS executor and include class4js module's loading statement to main module:

'use strict';

require('./class4js.js');

// Your code goes here...

NuGet

In Visual Studio class4js module can be installed using NuGet extension. To install class4js, run the following command in the package manager console.

Install-Package class4js

API

Class

A class is a construct that is used to create instances of itself. A class defines constituent members which enable its instances to have state and behavior. Private class members are decorated with __ and protected with _. Classes are declared by using the keyword $class:

$class(properties:Object, parent:Object, interfaces:Array): Function

Example:

var Shape = $class({
  __construct__: function () {
    this.__x = 0;
    this.__y = 0;
  },
  x: {
    get: function () {
      return this.__x;
    },
    set: function (value) {
      this.__x = value;
    }
  },
  y: {
    get: function () {
      return this.__y;
    },
    set: function (value) {
      this.__y = value;
    }
  },
  draw: function () {
    console.log("Drawing shape at: (" + this.x + ", " + this.y + ")");
  }, 
  moveTo: function (x, y) {
    this.x = x;
    this.y = y;
  }
});

var shape = new Shape({ x: 100, y: 100 });
shape.moveTo(120, 85);
shape.draw();   

Constructor

Whenever a class is created, its constructor is called. Name for a constructor is __construct__.

Example:

var Shape = $class({
  __construct__: function () {
    // Your code goes here...
  }
});

Static Constructor

Static constructor is a static data initializer. Static constructors are called when the class is defined. Name for a static constructor is the same as ordinal constructor name, but must be surrounded by __static__ statement.

Example:

var Shape = $class({
  __static__: {
    __construct__: function () {
      // Your code goes here...
    }
  }
});

Object Initializer

Object can be initialized with anonymous object. All properties from anonymous object are copied to the target object.

Example:

var Shape = $class({
  __construct__: function () {
    this.__x = 0;
    this.__y = 0;
  },
  x: {
    get: function () {
      return this.__x;
    },
    set: function (value) {
      this.__x = value;
    }
  },
  y: {
    get: function () {
      return this.__y;
    },
    set: function (value) {
      this.__y = value;
    }
  }
});

var shape = new Shape({ x: 100, y: 100 });

Constant

A constant is a class member which value can't be changed. Constant names should be in uppercasing.

Example:

var Calendar = $class({
  MONTHS: 12,
  WEEKS: 52,
  DAYS: 365,
});

Fields

All class fields should be defined as class members or initialized in constructor, because when class is created, class is closed for modifications.

Example:

var Shape = $class({
  __x: 0,
  __y: 0
});

Properties

A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field.

Example:

var Shape = $class({
  __construct__: function () {
    this.__x = 0;
    this.__y = 0;
  },
  x: {
    get: function () {
      return this.__x;
    },
    set: function (value) {
      this.__x = value;
    }
  },
  y: {
    get: function () {
      return this.__y;
    },
    set: function (value) {
      this.__y = value;
    }
  }
});

Static members

Static class members are used to create data and functions that can be accessed without creating an instance of the class. All static class members should be must be surrounded by __static__ statement.

Example:

var Calculator = $class({
  __static__: {
    sum: function (a, b) {
      return a + b;
    },
    subtract: function (a, b) {
      return a - b;
    }
  }
});

var result = Calculator.sum(2, 2);

Inheritance

Inheritance is a way to reuse code and to establish a subtype from an existing object. Constructor inheritance is also supported. To access parent's method, argument $super should be used. It must be the first argument in method definition. $super argument is optional.

Example:

var Shape = $class({
  __construct__: function () {
    this.__x = 0;
    this.__y = 0;
  },
  x: {
    get: function () {
      return this.__x;
    },
    set: function (value) {
      this.__x = value;
    }
  },
  y: {
    get: function () {
      return this.__y;
    },
    set: function (value) {
      this.__y = value;
    }
  },
  draw: function () {
    console.log("Drawing shape at: (" + this.x + ", " + this.y + ")");
  }
});

var Rectangle = $class({
  __construct__: function () {
    this.__width = 0;
    this.__height = 0;
  },
  width: {
    get: function () {
      return this.__width;
    },
    set: function (value) {
      this.__width = value;
    }
  },
  height: {
    get: function () {
      return this.__height;
    },
    set: function (value) {
      this.__height = value;
    }
  },
  draw: function ($super) {
    $super.draw();
    console.log("Drawing rectangle (" + this.width + ", " + this.height 
      + ") at: (" + this.x + ", " + this.y + ")");
  }
}, Shape);

var shape = new Shape({ x: 100, y: 100, with: 50, height: 50 });
shape.draw();

Abstract Class

Abstract class is intended only to be a base class of other classes. Abstract class can't be instantiated. Abstract classes are declared by using the keyword $abstract_class.

$abstract_class(properties:Object, parent:Object, interfaces:Array): Function

Example:

var Component = $abstract_class({
  __construct__: function () { 
    this.__name = 'Component';
  },
  name: { 
    get: function () { 
      return this.__name; 
    },
    set: function (value) { 
      this.__name = value; 
    }
  }
}); 

var Button = $class({
  __construct__: function () {
    this.name = 'Button1';
  }
}, Component)

try {
  var component = new Component(); 
} catch (ex) {
  console.log(ex.message);
} 

var button = new Button();

Static Class

Static class can't be initialized or inherited and contains only static members. Abstract classes are declared by using the keyword $static_class.

$static_class(properties:Object): Object

Example:

var Counter = $static_class({
  __construct__: function () {
    this.__value = 0;
  },
  increment: function () {
    this.__value++;
  },
  current: {
    get: function () {
      return this.__value;
    }
  }
});

Counter.increment();

Enum

$enum keyword can be used to set up collections of named integer constants.

$enum(fields:Object): Object

Example:

var Priority = $enum({
  LOW: 0,
  NORMAL: 1,
  HIGH: 2
});

Interface

Interfaces form a contract between the class and the outside world. If your class claims to implement an interface, all methods defined by that interface must appear in its source code. Interfaces are declared by using the keyword $interface.

$interface(properties:Object, parent:Object): Object

You can check if object is compatible with given interface or inherit given class.

$is(source:Object, target:Object): Boolean 

A class can inherit one or more interfaces.

Example:

var IComponent = $interface({ 
  name: {
    get: function () {}
  }
});

var IDrawable = $interface({
  draw: function (context) {} 
}, IComponent);

var Shape = $class({
  __construct__: function () {
    this.__name = 'Shape';
  },
  name: {
    get: function () {
      return this.__name;
    }
  },
  draw: function () {
    console.log("Drawing shape at: (" + this.x + ", " + this.y + ")");
  }
}, IDrawable);

var shape = new Shape();

console.log($is(shape, IDrawable));

Object factory

Object can be created by given type and initialized from anonymous object. To accomplish such task keyword $create is used.

$create(type:Function, options:Object): Object

Example:

var Shape = $class({
  __construct__: function () {
    this.__x = 0;
    this.__y = 0;
  },
  x: {
    get: function () {
      return this.__x;
    },
    set: function (value) {
      this.__x = value;
    }
  },
  y: {
    get: function () {
      return this.__y;
    },
    set: function (value) {
      this.__y = value;
    }
  }
});

var Layer = $class({
  __construct__: function () {
    this.__shapes = [];
  },
  add: function (options) {
    this.__shapes.push($create(Shape, options));
  }
});

var layer = new Layer();
layer.add({ x: 10, y: 10 });

All properties from anonymous object can be copied to existing object. To accomplish such task keyword $init is used.

$init(target:Object, options:Object): void

Example:

var Shape = $class({
  __construct__: function () {
    this.__x = 0;
    this.__y = 0;
  },
  x: {
    get: function () {
      return this.__x;
    },
    set: function (value) {
      this.__x = value;
    }
  },
  y: {
    get: function () {
      return this.__y;
    },
    set: function (value) {
      this.__y = value;
    }
  }
});

var shape = new Shape();
$init(shape, { x: 10, y: 10 });

Module

Modules were included to class4js for better compatability with browsers. Browsers don't have a built in module system. In Node.js modules are based on internal module loading. Modules are declared by using the keyword $module.

$module(scope:Function, dependencies:Array): Object

Example:

$config({
  debug: true,
  modules: [{
    name: 'a',
    path: './a.js'
  }]
});

var external_module = {};

var util = $module(function (fs, a, em, exports, global) {
  var Reader = $class({
    __construct__: function () {
    },  
    read: function () {
      console.log("Reading...");  
    }  
  }); 
  exports.Reader = Reader;
}, ['fs', 'a', external_module]);

var reader = new util.Reader();
reader.read();

Namespace

Namespaces are declared using the keyword $namespace. Namespaces help avoid naming collisions or excessive name prefixing.

$namespace(name:String, items:Object): void

Example:

$namespace('org.myapp.util');

org.myapp.util = (function () {
  var util = {};
  return util;
}());

Namespaces can be used within modules.

Example:

var myapp = $module(function (myapp) {

  $namespace('myapp.visual.common');

  myapp.visual.common.Button = $class({
    // Code goes here....
  });

});

Also class can be used within namespace.

Example:

$namespace('myapp.visual', {
  Shape: $class({
    __construct__: function () {

    },
    draw: function () {

    }
  })
});

Extension

Extensions enables you to add methods to existing types without creating a new derived type.

$extend(target:Object, name:String, value:Function): void

Example:

var ICollection = $interface({
  items: function() {
  }
});

var Collection = $class({
  __construct__: function (items) {
    this.__items = items;
  },
  items: function () {
    return this.__items;
  }
}, ICollection);

$extend(ICollection, 'forEach', function (callback) {
  if (callback) {
    for (var i = 0; i < this.items().length; i++) {
      callback(this.items()[i]);
    } 
  } 
});

var collection = new Collection([1, 2, 3]);
collection.forEach(function (item) {
  console.log(item);
});

License

This software is distributed under the terms of the GNU General Public License, version 3 (GPL-3.0).

npm loves you