поддерживается приватные свойства, статические свойства, протектед свойства, и наследование.
вот её реализация для ui:
wrapMethod = function(method, parentMethod, privatePrefix, Class) {
var wrapper;
wrapper = function() {
var privateBk, returns, staticBk, superBk;
superBk = this["super"];
privateBk = this["private"];
staticBk = this["static"];
if (this['__privates__']) {
if (!this['__privates__'][privatePrefix]) {
this['__privates__'][privatePrefix] = Object.create(null);
}
this["private"] = this['__privates__'][privatePrefix];
}
this["super"] = parentMethod;
this["static"] = Class;
returns = method.apply(this, arguments);
this["super"] = superBk;
this["private"] = privateBk;
this["static"] = staticBk;
return returns;
};
wrapper.toString = function() {
return method.toString();
};
return wrapper;
};
extend = function(Parent, Child) {
var Class, descriptor, emptyFuncRegExp, get, key, method, newPrototype, parentMethod, privatePrefix, set, value, wrapper, _i, _len, _ref;
if (!Child) {
Child = Parent;
Parent = Object;
}
if (!Parent) {
Parent = Object;
}
if (typeof Parent === 'string') {
Parent = ui.controller(Parent);
}
Class = function() {
var constructor, returns;
if (!this.hasOwnProperty('super')) {
Object.defineProperty(this, 'super', {
writable: true
});
}
if (!this.hasOwnProperty('private')) {
Object.defineProperty(this, 'private', {
writable: true
});
}
if (!this.hasOwnProperty('static')) {
Object.defineProperty(this, 'static', {
writable: true
});
}
if (!this.hasOwnProperty('__privates__')) {
Object.defineProperty(this, '__privates__', {
value: Object.create(null)
});
}
constructor = Class.prototype.constructor;
returns = constructor.apply(this, arguments);
if (returns instanceof constructor && !(returns instanceof Class)) {
return this;
}
if (returns === Object(returns)) {
return returns;
} else {
return this;
}
};
privatePrefix = Math.random()+''
newPrototype = Object.create(Parent.prototype);
emptyFuncRegExp = /^function\s*\S*\s*\(.*?\)\s*\{\s*}$/img;
_ref = Object.getOwnPropertyNames(Child.prototype);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
key = _ref[_i];
if (!Child.prototype.hasOwnProperty(key)) {
continue;
}
descriptor = Object.getOwnPropertyDescriptor(Child.prototype, key);
method = descriptor.value;
set = descriptor.set;
get = descriptor.get;
if (typeof method === 'function') {
if (key === 'constructor' && emptyFuncRegExp.test(method)) {
continue;
}
parentMethod = Parent.prototype[key];
wrapper = wrapMethod(method, parentMethod, privatePrefix, Class);
descriptor.value = wrapper;
}
if (typeof set === 'function') {
descriptor.set = wrapMethod(set, void 0, privatePrefix, Class);
}
if (typeof get === 'function') {
descriptor.get = wrapMethod(get, void 0, privatePrefix, Class);
}
Object.defineProperty(newPrototype, key, descriptor);
}
Class.prototype = newPrototype;
for (key in Child) {
if (!__hasProp.call(Child, key)) continue;
value = Child[key];
Class[key] = value;
}
Class.isClass = true;
Class.toString = function() {
return Class.prototype.constructor.toString();
};
return Class;
};
// #################### ПРИМЕР ИСПОЛЬЗОВАНИЯ ####################
function Animal(){
this.private.name = 'Animal'
}
Animal.prototype.say = function(){
alert(this.private.name)
}
function Cat(){
this.super()
this.private.name = 'Cat'
}
Cat.prototype.say = function(){
this.super()
alert(this.private.name)
}
// наследуем
Cat = extend(Animal, Cat)
cat = new Cat()
cat.say() // запускаем