Contains the Class Function for easily creating, extending, and implementing reusable Classes.

License:
MIT-style license.
  1. 17
  2. 18
  3. 19
  4. 20
  5. 21
  6. 22
  7. 23
  8. 24
  9. 25
  10. 26
  11. 27
  12. 28
  13. 29
  14. 30
  15. 31
  16. 32
  17. 33
  18. 34
  19. 35
  20. 36
  21. 37
  22. 38
  23. 39
  24. 40
  25. 41
  26. 42
  27. 43
  28. 44
  29. 45
  30. 46
  31. 47
  32. 48
  33. 49
(function(){ var Class = this.Class = new Type('Class', function(params){ if (instanceOf(params, Function)) params = {initialize: params}; var newClass = function(){ reset(this); if (newClass.$prototyping) return this; this.$caller = null; var value = (this.initialize) ? this.initialize.apply(this, arguments) : this; this.$caller = this.caller = null; return value; }.extend(this).implement(params); newClass.$constructor = Class; newClass.prototype.$constructor = newClass; newClass.prototype.parent = parent; return newClass; }); var parent = function(){ if (!this.$caller) throw new Error('The method "parent" cannot be called.'); var name = this.$caller.$name, parent = this.$caller.$owner.parent, previous = (parent) ? parent.prototype[name] : null; if (!previous) console.dir(this.$caller) if (!previous) throw new Error('The method "' + name + '" has no parent.'); return previous.apply(this, arguments); }; var indexOf = Array.prototype.indexOf;

Speedup1: Avoid typeOf in reset

before: switch (typeOf(value)){ case ‘object’: case ‘array’:

after:

  1. 58
  2. 59
  3. 60
  4. 61
  5. 62
  6. 63
  7. 64
  8. 65
  9. 66
  10. 67
  11. 68
  12. 69
  13. 70
  14. 71
  15. 72
  16. 73
  17. 74
  18. 75
  19. 76
  20. 77
  21. 78
  22. 79
  23. 80
  24. 81
  25. 82
  26. 83
var reset = function(object){ for (var key in object){ var value = object[key]; if (value && typeof(value) == 'object') { if (value.indexOf != indexOf) { var F = function(){}; F.prototype = value; object[key] = reset(new F); } else object[key] = value.clone(); } } return object; }; var wrap = function(self, key, method){ if (method.$origin) method = method.$origin; var wrapper = function(){ if (method.$protected && this.$caller == null) throw new Error('The method "' + key + '" cannot be called.'); var caller = this.caller, current = this.$caller; this.caller = current; this.$caller = wrapper; var result = method.apply(this, arguments); this.$caller = current; this.caller = caller; return result; }.extend({$owner: self, $origin: method, $name: key}); return wrapper; };

Speedup 2: Avoid typeOf in implement

  1. 86
  2. 87
  3. 88
  4. 89
  5. 90
  6. 91
  7. 92
  8. 93
  9. 94
  10. 95
  11. 96
  12. 97
  13. 98
  14. 99
  15. 100
  16. 101
  17. 102
  18. 103
  19. 104
  20. 105
  21. 106
  22. 107
  23. 108
  24. 109
  25. 110
  26. 111
  27. 112
  28. 113
  29. 114
  30. 115
  31. 116
  32. 117
  33. 118
  34. 119
  35. 120
  36. 121
  37. 122
  38. 123
  39. 124
  40. 125
  41. 126
  42. 127
  43. 128
var apply = Function.prototype.apply var implement = function(key, value, retain){ if (Class.Mutators.hasOwnProperty(key)){ value = Class.Mutators[key].call(this, value); if (value == null) return this; } if (value && value.call && (value.apply == apply)){ if (value.$hidden) return this; this.prototype[key] = (retain) ? value : wrap(this, key, value); } else { Object.merge(this.prototype, key, value); } return this; }; var getInstance = function(klass){ if (!klass) debugger klass.$prototyping = true; var proto = new klass; delete klass.$prototyping; return proto; }; Class.implement('implement', implement.overloadSetter()); Class.Mutators = { Extends: function(parent){ this.parent = parent; this.prototype = getInstance(parent); }, Implements: function(items){ Array.from(items).each(function(item){ var instance = new item; for (var key in instance) implement.call(this, key, instance[key], true); }, this); } }; })();