Added support for _super method
- Motivation from John Reisg's "Simple Javascript Inheritance": http://ejohn.org/blog/simple-javascript-inheritance/closure/master
parent
6ea6fd0bb7
commit
607bbf7f4c
28
lib/class.js
28
lib/class.js
|
@ -47,9 +47,37 @@ var prop_copy = function( props, dest )
|
||||||
{
|
{
|
||||||
// copy each of the properties to the destination object
|
// copy each of the properties to the destination object
|
||||||
for ( property in props )
|
for ( property in props )
|
||||||
|
{
|
||||||
|
// 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 ];
|
dest[ property ] = props[ property ];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ var Foo = Class.extend(
|
||||||
{
|
{
|
||||||
hitMethod: false,
|
hitMethod: false,
|
||||||
hitMethod2: false,
|
hitMethod2: false,
|
||||||
|
method2Arg: null,
|
||||||
|
|
||||||
myMethod: function()
|
myMethod: function()
|
||||||
{
|
{
|
||||||
|
@ -38,9 +39,11 @@ var Foo = Class.extend(
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
myMethod2: function()
|
myMethod2: function( arg )
|
||||||
{
|
{
|
||||||
this.hitMethod2 = true;
|
this.hitMethod2 = true;
|
||||||
|
this.method2Arg = arg;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -52,9 +55,9 @@ var SubFoo = Foo.extend(
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
myMethod2: function()
|
myMethod2: function( arg )
|
||||||
{
|
{
|
||||||
return this._super();
|
return this.__super( arg );
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -74,6 +77,9 @@ assert.equal(
|
||||||
"Sanity check"
|
"Sanity check"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var arg = 'foobar';
|
||||||
|
sub_foo.myMethod().myMethod2( arg );
|
||||||
|
|
||||||
// myMethod overrides without calling parent
|
// myMethod overrides without calling parent
|
||||||
assert.equal(
|
assert.equal(
|
||||||
sub_foo.hitMethod,
|
sub_foo.hitMethod,
|
||||||
|
@ -81,9 +87,16 @@ assert.equal(
|
||||||
"Subtype should be able to override parent properties"
|
"Subtype should be able to override parent properties"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// myMethod2 overrides parent then calls super method
|
||||||
assert.equal(
|
assert.equal(
|
||||||
sub_foo.hitMethod2,
|
sub_foo.hitMethod2,
|
||||||
true,
|
true,
|
||||||
"Subtype should be able to call parent method"
|
"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"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue