diff --git a/lib/class.js b/lib/class.js index 539ec28..ed5fa15 100644 --- a/lib/class.js +++ b/lib/class.js @@ -48,7 +48,35 @@ var prop_copy = function( props, dest ) // copy each of the properties to the destination object for ( property in props ) { - dest[ property ] = props[ property ]; + // if the property already exists, then it's being overridden (we only + // care about methods - properties will simply have their values + // overwritten) + var pre = dest[ property ]; + if ( ( pre !== undefined ) && ( pre instanceof Function ) ) + { + dest[ property ] = ( function( method, super_method ) + { + // this is the method that will be invoked when the requested + // method is called, so note that in the context of this + // function, `this` will represent the current class instance + return function() + { + var tmp = this.__super; + + // assign _super temporarily for the method invocation so + // that the method can call the parent method + this.__super = super_method; + var retval = method.apply( this, arguments ); + this.__super = tmp; + + return retval; + } + })( props[ property ], dest[ property ] ); + } + else + { + dest[ property ] = props[ property ]; + } } } diff --git a/test/test-class-parent.js b/test/test-class-parent.js index 55fbca8..5e52d57 100644 --- a/test/test-class-parent.js +++ b/test/test-class-parent.js @@ -31,6 +31,7 @@ var Foo = Class.extend( { hitMethod: false, hitMethod2: false, + method2Arg: null, myMethod: function() { @@ -38,9 +39,11 @@ var Foo = Class.extend( return this; }, - myMethod2: function() + myMethod2: function( arg ) { this.hitMethod2 = true; + this.method2Arg = arg; + return this; }, }); @@ -52,9 +55,9 @@ var SubFoo = Foo.extend( return this; }, - myMethod2: function() + myMethod2: function( arg ) { - return this._super(); + return this.__super( arg ); }, }); @@ -74,6 +77,9 @@ assert.equal( "Sanity check" ); +var arg = 'foobar'; +sub_foo.myMethod().myMethod2( arg ); + // myMethod overrides without calling parent assert.equal( sub_foo.hitMethod, @@ -81,9 +87,16 @@ assert.equal( "Subtype should be able to override parent properties" ); +// myMethod2 overrides parent then calls super method assert.equal( sub_foo.hitMethod2, true, "Subtype should be able to call parent method" ); +assert.equal( + sub_foo.method2Arg, + arg, + "Arguments should be passed to super method via _super argument list" +); +