// Extend
function extend (child, parent) {
var key;
function F () {}
if (isTypeOf(child, 'Object') && isTypeOf(parent, 'Object')) {
for (key in parent) {if (parent.hasOwnProperty(key)) {child[key] = parent[key];}}
} else if (isTypeOf(child, 'Function') && isTypeOf(parent, 'Object')) {
child.prototype = parent;
child.prototype.constructor = child;
} else if (isTypeOf(child, 'Function') && isTypeOf(parent, 'Function')) {
for (key in parent) {if (parent.hasOwnProperty(key)) {child[key] = parent[key];}}
F.prototype = parent.prototype;
child.prototype = new F();
child.prototype.constructor = child;
}
}
// Mixin
function mixin (child) {
var mixins = Array.prototype.slice.call(arguments, 1);
if (not(isEmpty(mixins))) {
if (isTypeOf(mixins[0], 'Array')) {mixins = mixins[0];}
forEachIn(mixins, function(mixinClass){
forEachIn(mixinClass, function(propertyInClass, propertyName){if (mixinClass.hasOwnProperty(propertyName)) {child[propertyName] = propertyInClass;}});
forEachIn(mixinClass.prototype, function(propertyInPrototype, propertyName){if (propertyName !== 'constructor') {child.prototype[propertyName] = propertyInPrototype;}});
});
}
}
// Class
function ParentClass (initVar) {
this.initVar = initVar;
this.defaultVar = 'ParentClass default var inside constructor.';
this._x = 0;
document.addEventListener('click', this._eventFunction, false);
}
// Static
ParentClass.staticMethod = function () {return 'ParentClass static method.'};
// Default
ParentClass.prototype.defaultVar = 'ParentClass default var inside prototype.';
// Public
ParentClass.prototype.destroy = function () {document.removeEventListener('click', this._eventFunction, false);};
ParentClass.prototype.publicMethod = function () {return 'ParentClass public method.';};
// Private
ParentClass.prototype._privateMethod = function () {return 'ParentClass private method call ' + this.initVar;};
ParentClass.prototype._eventFunction = function () {alert(1);};
// Getters and Setters
Object.defineProperty(ParentClass.prototype, "x", {
get: function () {return this._x;}
, set: function (value) {this._x = value;}
, enumerable: true
, configurable: true
});
// Tests
var parentObject = new ParentClass('ParentClass init var');
console.dir(ParentClass);
console.dir(ParentClass.prototype);
console.log(parentObject.constructor.name);
console.log(parentObject.defaultVar);
delete parentObject.defaultVar;
console.log(parentObject.defaultVar);
console.log(parentObject.initVar);
console.log(parentObject.publicMethod());
console.log(parentObject._privateMethod());
console.log(ParentClass.staticMethod());
parentObject.x = 1;
console.log('ParentClass getter x=' + parentObject.x);
setTimeout(function () {console.log('Object destruction.'); parentObject.destroy(); parentObject = null; }, 5000);
console.log('---------------------------------------------');
// Class
function MixinClass() {}
// Static
MixinClass.mixinStaticMethod = function () {return 'MixinClass static method.';};
// Public
MixinClass.prototype.mixinPublicMethod = function () {return 'MixinClass public method.';};
// Class
function ChildClass (initVar) {
if (ChildClass.instance) {return ChildClass.instance;} ChildClass.instance = this;
ParentClass.call(this, initVar);
this._y;
var privateVar = 'ChildClass private var.';
function privateFunction() {return 'ChildClass private function can show ' + privateVar + ' and ' + ParentClass.prototype._privateMethod.call(ChildClass.instance);}
console.log(privateFunction());
return ChildClass.instance;
}
// Extend
extend(ChildClass, ParentClass);
// Mixin
mixin(ChildClass, MixinClass);
// Singleton
ChildClass.instance = undefined;
// Override
ChildClass.prototype.destroy = function () {console.log('ChildClass destroyed.');};
ChildClass.prototype.publicMethod = function () {return 'ChildClass public method.';};
// Getters and Setters
Object.defineProperty(ChildClass.prototype, "y", {
get: function () {return this._y;}
, set: function (value) {this._y = value;}
, enumerable: true
, configurable: true
});
// Tests
var childObject = new ChildClass('ChildClass init var');
var childObject2 = new ChildClass('ChildClass init var 2');
console.dir(ChildClass);
console.dir(ChildClass.prototype);
console.log('Is singleton? ' + (childObject === childObject2));
console.log(childObject.constructor.name);
console.log(childObject.defaultVar);
console.log(childObject.initVar);
console.log(childObject.publicMethod());
console.log(childObject._privateMethod());
console.log(ChildClass.staticMethod());
childObject.x = 2;
console.log('ChildClass getter x=' + childObject.x);
childObject.y = 5;
console.log('ChildClass getter y=' + childObject.y);
console.log(childObject.mixinPublicMethod());
console.log(ChildClass.mixinStaticMethod());
setTimeout(function () {console.log('Object destruction.'); childObject.destroy(); childObject = null;}, 5000);
Комментариев нет:
Отправить комментарий