Permalink
Browse files

- simplified **a lot** the Extends Mutator for Class. Fixes some bug…

…s (thanks RD for reporting), and Its now faster than ever, as it doesnt create a new closure for subclassed methods.

Technical Explanation:

Now when you subclass, a property named _parent_ is simply attached to every "subclassed" method. Then, thanks to the caller property, we can retrieve the right parent based on the method we're on by calling "this.parent". This obviously works regardless of how many levels of subclasses we have. The parent assignment used to be in real time (right before each method was called, in a closure, basically how it was done in the original Base.js, not sure how it is now with Base2), but the caller property allows us to avoid it, and all we need now is simply a property.

git-svn-id: http://svn.mootools.net/trunk@1535 4db308c1-fb21-0410-9919-de62e267375e
  • Loading branch information...
kamicane
kamicane committed Apr 12, 2008
1 parent 974d630 commit c87cd7700307b43bf71fa65ffc8a074d9a9e331f
Showing with 28 additions and 24 deletions.
  1. +28 −24 Source/Class/Class.js
View
@@ -14,21 +14,22 @@ var Class = new Native({
properties = properties || {};
- var klass = function(){
-
+ var klass = function(empty){
+
for (var key in this) this[key] = $unlink(this[key]);
-
+
for (var mutator in Class.Mutators){
if (!this[mutator]) continue;
Class.Mutators[mutator](this, this[mutator]);
- delete this[mutator];
}
this.constructor = klass;
-
- var self = (arguments[0] !== $empty && this.initialize) ? this.initialize.apply(this, arguments) : this;
- if (this.options && this.options.initialize) this.options.initialize.call(this);
+ if (empty === $empty) return this;
+
+ var self = (this.initialize) ? this.initialize.apply(this, arguments) : this;
+ if (this.options && this.options.initialize) this.options.initialize.call(this);
+
return self;
};
@@ -59,27 +60,30 @@ Class.Mutators.Implements = function(self, klasses){
Class.Mutators.Extends = function(self, klass){
- var instance = new klass($empty), current;
+ var instance = new klass($empty);
- for (var key in instance) self[key] = (function(previous, current){
- if (current != undefined && previous != current){
- var type = $type(current), ptype = $type(previous);
- if (type != ptype) return current;
- switch (type){
- case 'function':
- return function(){
- current.parent = previous.bind(this);
- return current.apply(this, arguments);
- };
- case 'object': return $merge(previous, current);
- default: return current;
- }
+ for (var key in instance){
+
+ var current = self[key], previous = instance[key];
+
+ if (current == undefined){
+ self[key] = previous;
+ continue;
}
- return previous;
- })(instance[key], (current = self[key]));
+
+ var ctype = $type(current), ptype = $type(previous);
+
+ if (ctype != ptype) continue;
+
+ switch (ctype){
+ case 'function': self[key]._parent_ = previous; break;
+ case 'object': self[key] = $merge(previous, current);
+ }
+
+ }
self.parent = function(){
- return arguments.callee.caller.parent.apply(this, arguments);
+ return arguments.callee.caller._parent_.apply(this, arguments);
};
};

0 comments on commit c87cd77

Please sign in to comment.