<!DOCTYPE html>
<html>
<meta charset="utf-8" />
<head><title>JavaScript Class</title></head>
<body>
<script type="text/javascript">
//----------------------------------------------------------------------------
// Наследование дочерним классом всех свойств и методов из родительского класса
var extend = this.extend || function (childClass, parentClass) {
// Копируем в дочерний класс статичные свойства и методы из родительского класса
for (var key in parentClass) {
if (parentClass.hasOwnProperty(key)) {childClass[key] = parentClass[key];}
}
// Копируем в дочерний класс свойства и методы из прототипа родительского класса
function F () {} // Временная функция
F.prototype = parentClass.prototype; // Копируем свойства и методы прототипа из родителя во временную функцию
childClass.prototype = new F(); // Присваиваем дочернему прототипу объект, созданный из родительского класса
childClass.prototype.constructor = childClass; // Ставим ссылку конструктора на дочерний класс
childClass.__super__ = parentClass.prototype; // Ссылка на родительский класс для непосредственного вызова родительских методов, если потребуется.
// __super__ можно использовать в методе дочернего класса, вызывая дополнительно метод родительского класса внутри него так: ChildClass.__super__.someMethod.call(this, 'some data');
};
// Копирование свойств и методов из примесей в класс
var mixin = this.mixin || function (childClass) {
var mixins = Array.prototype.slice.call(arguments, 1) // Классы с набором методов mixin
, i
, len = mixins.length
, key;
if (len) {
// Для каждого элемента из массива mixins копируем статичные свойства и методы в дочерний класс
for (i = 0; i < len; i++) {
// Копируем в класс статичные свойства и методы из примеси
for (key in mixins[i]) {
if (mixins[i].hasOwnProperty(key)) {childClass[key] = mixins[i][key];}
}
// Копируем в прототип класса свойства и методы из прототипа примеси
for (key in mixins[i].prototype) {
childClass.prototype[key] = mixins[i].prototype[key];
}
}
}
};
//----------------------------------------------------------------------------
var AbstractClass = (function(){
// Constructor
function AbstractClass () {}
// Initializer (getInstance)
AbstractClass.newInstance = function () {
var instance = new AbstractClass();
return instance;
};
// Parent class link
AbstractClass.__super__ = Object.prototype;
// Destroyer (destroy)
AbstractClass.prototype.deleteInstance = function (referenceName) {
// Удаление экземпляра класса из памяти (необяхательно нужно)
eval(
referenceName + '= null;' // Устанавливая referenceName равным null, мы удаляем ссылку на объект
+ ' delete ' + referenceName + ';' // далее можем удалить и сам объект
);
};
return AbstractClass;
})();
//----------------------------------------------------------------------------
// AbstractClass Test
var abstractObject = AbstractClass.newInstance();
console.log(abstractObject.constructor.name);
console.log(AbstractClass.__super__);
// abstractObject.deleteInstance('abstractObject'); // Удаление ссылки на объект из JavaScript
console.log('AbstractClass instance: ' + abstractObject);
//----------------------------------------------------------------------------
var ParentClass = (function(parentClass){
// Extend
extend(ParentClass, parentClass);
// Constructor
function ParentClass () {}
// Initializer
ParentClass.newInstance = function (initVar, initMethod) {
// Instance
var instance = new ParentClass();
// Init public
instance.initVar = initVar;
instance.initMethod = initMethod;
// Privilege public
instance.privilegeVar = 'ParentClass privilege public variable.';
instance.privilegeMethod = function () {return 'ParentClass privilege public method.' + ' ' + privateVar + ' ' + privateFunction();};
// Private
var privateVar = 'ParentClass private variable.';
function privateFunction () {return 'ParentClass private function.';}
// Events
instance.eventFunction = function () {instance._privateMethod(instance);}
document.addEventListener('click', function(){alert('This event can\'t be remove.' + ' ' + instance.privilegeVar);}, false);
document.addEventListener('click', instance.eventFunction, false);
// Return instance
return instance;
};
// Destroyer
ParentClass.prototype.deleteInstance = function (referenceName) {
document.removeEventListener('click', this.eventFunction, false);
// Удаление экземпляра класса из памяти (необяхательно нужно)
eval(
referenceName + '= null;' // Устанавливая referenceName равным null, мы удаляем ссылку на объект
+ ' delete ' + referenceName + ';' // далее можем удалить и сам объект
);
};
// Default value - будет браться значение по умолчанию, если данное свойство будет удалено или не будет определено
ParentClass.prototype.initVar = 'ParentClass default variable.';
// Private
ParentClass.prototype._privateMethod = function (instance) {
alert('This event can be remove.' + ' ' + instance.privilegeVar);
};
// Public
ParentClass.prototype.publicMethod = function () {
return 'ParentClass public method.' + ' ' + this.privilegeVar;
};
// Static
ParentClass.staticVar = 'ParentClass static variable.';
ParentClass.staticMethod = function () {return 'ParentClass static method.';};
return ParentClass;
})(AbstractClass);
//----------------------------------------------------------------------------
// ParentClass Test
var parentObject = ParentClass.newInstance('ParentClass init public variable.', function () {return 'ParentClass init public method.' + ' ' + this.initVar;});
console.log(parentObject.constructor.name);
console.log(ParentClass.__super__);
console.log(parentObject.initMethod());
console.log(parentObject.privilegeVar);
console.log(parentObject.privilegeMethod());
parentObject._privateMethod(parentObject);
console.log(parentObject.publicMethod());
console.log(ParentClass.staticVar);
console.log(ParentClass.staticMethod());
setTimeout(function (){parentObject.deleteInstance('parentObject'); console.log('ParentClass instance: ' + parentObject);}, 5000);
//----------------------------------------------------------------------------
var MixinClass = (function(){
// Constructor
function MixinClass () {}
// Public
MixinClass.prototype.mixinPublicMethod = function () {return 'MixinClass public method.';};
// Static
MixinClass.mixinStaticMethod = function () {return 'MixinClass static method.';};
return MixinClass;
})();
//----------------------------------------------------------------------------
var ChildClass = (function(parentClass){
// Extend
extend(ChildClass, parentClass);
// Constructor
function ChildClass () {}
// Initializer
ChildClass.newInstance = function (initVar, initMethod) {
// Instance
var instance = new ChildClass();
// Parent Constructor Call (Несовместимо с Mixin)
// instance = parentClass.newInstance.apply(instance, arguments);
// Init public
instance.initVar = initVar;
instance.initMethod = initMethod;
// Privilege public
instance.privilegeVar = 'ChildClass privilege public variable.';
instance.privilegeMethod = function () {return 'ChildClass privilege public method.' + ' ' + privateVar + ' ' + privateFunction();};
// Private
var privateVar = 'ChildClass private variable.';
function privateFunction () {return 'ChildClass private function.';}
// Events
instance.eventFunction = function () {instance._privateMethod(instance);}
document.addEventListener('click', function(){alert('This event can\'t be remove.' + ' ' + instance.privilegeVar);}, false);
document.addEventListener('click', instance.eventFunction, false);
// Call parentClass method
console.log(ChildClass.__super__.publicMethod.call(instance));
console.log(parentClass.staticMethod());
// Return instance
return instance;
};
// Override Public
ChildClass.prototype.publicMethod = function () {
return 'ChildClass public method.' + ' ' + this.privilegeVar;
};
// Mixin
mixin(ChildClass, MixinClass);
return ChildClass;
})(ParentClass);
//----------------------------------------------------------------------------
// ChildClass Test
var childObject = ChildClass.newInstance('ChildClass init public variable.', function () {return 'ChildClass init public method.' + ' ' + this.initVar;});
console.log(childObject.constructor.name);
console.log(ChildClass.__super__);
console.log(childObject.initMethod());
console.log(childObject.privilegeVar);
console.log(childObject.privilegeMethod());
childObject._privateMethod(childObject);
console.log(childObject.publicMethod());
console.log(ChildClass.staticVar);
console.log(ChildClass.staticMethod());
console.log(childObject.mixinPublicMethod());
console.log(ChildClass.mixinStaticMethod());
setTimeout(function (){childObject.deleteInstance('childObject'); console.log('ChildClass instance: ' + childObject);}, 5000);
//----------------------------------------------------------------------------
var SingletonClass = (function(parentClass){
// Extend
extend(SingletonClass, parentClass);
// Constructor
function SingletonClass () {}
// Static instance
SingletonClass.instance = undefined;
// Initializer
SingletonClass.newInstance = function (initVar, initMethod) {
// Return static singleton instance if singleton object exists
if (SingletonClass.instance) {return SingletonClass.instance;}
// Instance
var instance = new SingletonClass();
SingletonClass.instance = instance;
// Init public
instance.initVar = initVar;
instance.initMethod = initMethod;
// Privilege public
instance.privilegeVar = 'SingletonClass privilege public variable.';
instance.privilegeMethod = function () {return 'SingletonClass privilege public method.' + ' ' + privateVar + ' ' + privateFunction();};
// Private
var privateVar = 'SingletonClass private variable.';
function privateFunction () {return 'SingletonClass private function.';}
// Events
instance.eventFunction = function () {instance._privateMethod(instance);}
document.addEventListener('click', function(){alert('This event can\'t be remove.' + ' ' + instance.privilegeVar);}, false);
document.addEventListener('click', instance.eventFunction, false);
// Return instance
return instance;
};
return SingletonClass;
})(ChildClass);
//----------------------------------------------------------------------------
// SingletonClass Test
var firstSingletonObject = SingletonClass.newInstance('First SingletonClass init public variable.', function () {return 'First SingletonClass init public method.' + ' ' + this.initVar;});
var secondSingletonObject = SingletonClass.newInstance('Second SingletonClass init public variable.', function () {return 'Second SingletonClass init public method.' + ' ' + this.initVar;});
var thirdSingletonObject = SingletonClass.newInstance('Third Second SingletonClass init public variable.', function () {return 'Third SingletonClass init public method.' + ' ' + this.initVar;});
console.log('Is singleton? ' + (firstSingletonObject === secondSingletonObject && firstSingletonObject === thirdSingletonObject && secondSingletonObject === thirdSingletonObject).toString());
console.log(thirdSingletonObject.constructor.name);
console.log(SingletonClass.__super__);
console.log(thirdSingletonObject.initMethod());
console.log(thirdSingletonObject.privilegeVar);
console.log(thirdSingletonObject.privilegeMethod());
thirdSingletonObject._privateMethod(thirdSingletonObject);
console.log(thirdSingletonObject.publicMethod());
console.log(SingletonClass.staticVar);
console.log(SingletonClass.staticMethod());
setTimeout(function (){thirdSingletonObject.deleteInstance('thirdSingletonObject'); console.log('SingletonClass instance: ' + thirdSingletonObject);}, 5000);
//----------------------------------------------------------------------------
</script>
</body>
</html>
Комментариев нет:
Отправить комментарий