neatness v1.2.3
Neatness
Neatness - Full-Stack library for implementation OOP-style classes in JavaScript.
Neatness.defineClass('MyClass', {
name: 'Ivan'
});
var myClass = new MyClass();
console.log(myClass.name); // IvanSupported features
Namespaces
Set full class name (with namespace) for auto create namespace hierarchy.
Namespace in Neatness - is normal object, you can access to namespace items
via simple navigation my.namespace or via Neatness.namespace('my.namespace') method:
Neatness.defineClass('my.namespace.MyClass', {
name: 'Ivan'
});
var namespace = Neatness.namespace('my.namespace');
var myClass = new my.namespace.MyClass();Simple extends
Neatness supported simple (not multi) extends prototype and static properties and methods.
var Neatness = require('neatness');
var app = Neatness.namespace('app');
Neatness.defineClass('app.models.User', {
__extends: Neatness.Object,
role: 'user',
name: null,
constructor: function(name) {
this.name = name;
},
getRole: function() {
}
});
Neatness.defineClass('app.models.Operator', {
__extends: app.models.User,
role: 'operator'
});
var user = new app.models.User('John');
console.log(user.role); // user
console.log(user.name); // John
var user = new app.models.Operator('Sebastian');
console.log(user.role); // operatorUsage objects and arrays in class properties
All objects and arrays in prototypes will be cloned in inherited objects. But in static - do not.
Neatness.defineClass('app.models.Article', {
categories: ['news', 'other']
});
var article1 = new app.models.Article();
var article2 = new app.models.Article();
article1.categories.push('fun');
console.log(article2.categories); // ['news', 'other']Mixins
Mixin - is a class without constructor. This structure have only prototype and static methods and properties. Important! Mixin can only add method and properties, by not overwrite. If you class and used mixin have duplicate methods or properties, will be throws exceptions.
Neatness.defineClass('app.models.ViewMixin', {
getCategories: function() {
return this.categories.join(', ');
}
});
Neatness.defineClass('app.models.Article', {
__mixin: app.models.ViewMixin,
categories: ['news', 'other']
});
var article = new app.models.Article();
console.log(article.getCategories()); // 'news, other'Static properties and methods
Neatness.defineClass('app.models.Category', {
__static: {
TYPE_FUN: 'fun',
getAllTypes: function() {
return [ this.TYPE_FUN ];
}
}
});
console.log(app.models.Category.getAllTypes()); // ['fun']Easy call parent method via this.__super()
All methods in class have can call __super() method for call parent. Notice: You can use this call only for synchronous operations!
Neatness.defineClass('app.Base', {
getText: function(name) {
return 'Hello, ' + name + '.';
}
});
Neatness.defineClass('app.HelloWorld', {
__extends: app.Base,
getText: function(name) {
return this.__super(name) + ' Good luck!';
}
});
var helloWorld = new app.HelloWorld();
console.log(helloWorld.getText('John')); // 'Hello, John. Good luck!'Documentation
Neatness.defineClass(className, options)
classNameFull defined class name with namespace.optionsObject with prototype properties and methods.options.__extendsLink to class or string class name of extends class.options.__mixinLink to class or string class name of attached mixin.options.__mixinsLink to class or string class name of attached mixins.options.__staticObject with static properties and methods.- Method returns current class
Neatness.defineEnum(className, options)
classNameFull defined enum name with namespace.optionsKey-value object.- Method returns current enum
Neatness.defineEnum('app.AnswersEnum', {
YES: 'yes',
NO: 'no'
});
console.log(app.AnswerEnum.YES); // yesNeatness.namespace(path)
pathString of full namespace path- Method returns object of specified namespace
Neatness.newContext(removeGlobal)
removeGlobalBoolean flag, set true for remove Neatness object from window (browser global object)- Method returns new Neatness instance with new context. See section "Usage for libraries".
Access to class names
All classes, which defined through Neatness.defineClass() have next static and prototype properties:
__classNameFull current class name with namespace. Example:app.MyClass__instanceNameUnique instance name. Example:app.MyClass864__parentClassNameFull parent (extends) class name with namespace. Example:app.MyBaseClass__staticLink to used class. If you access to this property in extends classes, then you give top-level class. Example:
Neatness.defineClass('app.BaseClass', {
isMy: function() {
return this.__static === app.MyClass;
}
});
Neatness.defineClass('app.MyClass', {
__extends: app.BaseClass
});
console.log((new app.BaseClass()).isMy()); // false
console.log((new app.MyClass()).isMy()); // trueNeatness.Object
Base class for any you class. This class has not implementation and need for improvement navigation in IDE. Prototype methods:
className()Returns full class name with namespaceclassInstanceName()Returns unique instance nameparentClassName()Returns full parent class name with namespace
Neatness.Exception
Base class for you exceptions. This class extended from native JavaScript Error function and detect true stacktrace and error name.
Usage in Node.js
File main.js
var Neatness = require('neatness');
var app = Neatness.namespace('app');File app/MyClass.js
var Neatness = require('neatness');
Neatness.defineClass('app.MyClass', {
__extends: 'app.BaseClass'
});Usage for libraries
(function() {
// Included Neatness source code or Neatness in globally
// Create new context, set `true` flag for remove Neatness
// object from window (browser global object)
var Neatness = Neatness.newContext(true);
// Create namespace, which saved in created Neatness context
var app = Neatness.namespace('app');
// You library code
Neatness.defineClass('app.MyClass', {
});
})();Full class define example with jsdoc example
Neatness.defineClass('app.BaseUser', /** @lends app.BaseUser.prototype */{
__extends: Neatness.Object,
__static: /** @lends app.BaseUser */{
/**
* @type {string}
*/
text: 'my text',
/**
* @type {Array.<string|number>}
*/
customList: ['zero', 1, 50],
/**
* @returns {number}
*/
getNumber: function() {
return 3;
}
},
/**
* @type {string}
*/
_name: null,
/**
* @type {object}
*/
roleLabels: {
user: 'User',
operator: 'Operator'
},
/**
* @param {string} name User name
* @constructs
* @extends Neatness.Object
*/
constructor: function(name) {
this._name = name;
this.__super(name);
}
});
/**
* @class app.MyUser
* @extends app.BaseUser
*/
Neatness.defineClass('app.MyUser', /** @lends app.MyUser.prototype */{
__extends: tests.BaseClass,
/**
* @returns {null|string}
*/
getName: function() {
return this._name;
}
});Unit tests
All library coverage in node unit tests. You can run it's by:
nodeunit tests/unit