Advertisement
Guest User

Untitled

a guest
Jan 19th, 2017
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.21 KB | None | 0 0
  1. // base class
  2. function Class() { }
  3.  
  4. // base class name
  5. Class.prototype.className = 'Class';
  6.  
  7. // lists all parent classes and outputs JSON with it
  8. Class.prototype.toString = function() {
  9. var str = '';
  10. var next = this.__proto__;
  11. while(next && next.className) {
  12. str = next.className + ':' + str;
  13. next = next.__proto__;
  14. }
  15. return str.slice(0, -1) + ' ' + JSON.stringify(this);
  16. };
  17.  
  18. // check if class implements specific interface
  19. Class.prototype.implements = function(item) {
  20. var next = this;
  21. while(next) {
  22. if (next.classImplementations) {
  23. for(var i = 0, len = next.classImplementations.length; i < len; i++) {
  24. if (next.classImplementations[i] == item) {
  25. return true;
  26. }
  27. }
  28. }
  29. next = next.__proto__;
  30. }
  31. return false;
  32. };
  33.  
  34. // check if class extends another class
  35. Class.prototype.extends = function(item) {
  36. return this instanceof item;
  37. };
  38.  
  39. // check typeof class
  40. Class.prototype.typeof = function(item) {
  41. return item == Class;
  42. };
  43.  
  44. // implement class extension
  45. Class.extend = function(options) {
  46. // name is mandatory
  47. if (! options['name']) throw new Error('name option should be provided for a Class');
  48.  
  49. // check for reserved keys
  50. var reserved = [
  51. 'super',
  52. 'typeof', 'extends', 'implements',
  53. 'className', 'classImplementations', 'classConstructor'
  54. ];
  55. reserved.forEach(function(name) {
  56. if (options[name]) throw new Error('could not extend class ' + options['name'] + ' - ' + name + ' is reserved key');
  57. });
  58.  
  59. // keep in upper scope variables
  60. var _super = this.prototype;
  61. var className = options['name'];
  62. var classImplementations = options['implement'];
  63. var classConstructor = options['constructor'];
  64.  
  65. // class
  66. function proto(args) {
  67. args = args || { };
  68.  
  69. var i, len;
  70. // if first, call own constructor as well
  71. var first = ! args.__secondary;
  72. args.__secondary = true;
  73.  
  74. // call parent constructor
  75. _super.constructor.call(this, args);
  76. // for each implementation of parent
  77. if (_super.classImplementations) {
  78. for(i = 0, len = _super.classImplementations.length; i < len; i++) {
  79. // call its constructor
  80. _super.classImplementations[i].call(this);
  81. }
  82. }
  83. // if parent has consstructor, call it
  84. if (_super.classConstructor) {
  85. _super.classConstructor.call(this, args);
  86. }
  87. // if first
  88. if (first) {
  89. // check and call implementations
  90. if (classImplementations) {
  91. for(i = 0, len = classImplementations.length; i < len; i++) {
  92. classImplementations[i].call(this, args);
  93. }
  94. }
  95. // call own constructor
  96. classConstructor.call(this, args);
  97. }
  98. }
  99.  
  100. // inherit prototype
  101. proto.prototype = Object.create(this.prototype);
  102.  
  103. // implement
  104. if (options['implement']) {
  105. options['implement'].forEach(function(item) {
  106. for(var name in item.prototype) {
  107. proto.prototype[name] = item.prototype[name];
  108. }
  109. });
  110. }
  111.  
  112. // set constructor
  113. proto.prototype.constructor = proto;
  114.  
  115. // a way to call parents method
  116. proto.prototype.super = function(method, args) {
  117. if (! (args instanceof Array)) {
  118. args = [ args ];
  119. }
  120. return _super[method].apply(this, args);
  121. };
  122.  
  123. // check for typeof
  124. proto.prototype.typeof = function(item) {
  125. return item == proto;
  126. };
  127.  
  128. // rename options
  129. options['className'] = options['name'];
  130. options['classConstructor'] = options['constructor'].name != 'Object' ? options['constructor'] : function() { };
  131. options['classImplementations'] = options['implement'];
  132.  
  133. // remove garbage
  134. delete options['name'];
  135. delete options['constructor'];
  136. delete options['implement'];
  137.  
  138. // implement own extensions
  139. for(var name in options) {
  140. proto.prototype[name] = options[name];
  141. }
  142.  
  143. // allow class to be extended
  144. proto.extend = Class.extend;
  145.  
  146. // return class
  147. return proto;
  148. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement