coope/lst/ctor-factory.js

104 lines
1.9 KiB
JavaScript

var Class = ( function( extending )
{
var C = function( dfn )
{
// extend from an empty base
return C.extend( null, dfn );
};
C.extend = function( base, dfn )
{
base = base || function() {};
// prevent ctor invocation
extending = true;
var ctor = function()
{
// do nothing if extending
if ( extending )
{
return;
}
// call "actual" constructor
this.__construct &&
this.__construct.apply(
this, arguments
);
};
ctor.prototype = new base();
ctor.prototype.constructor = ctor;
copyTo( ctor.prototype, dfn );
// done extending; clear flag to
// ensure ctor can be invoked
extending = false;
return ctor;
};
function copyTo( dest, members )
{
var hasOwn = Object.prototype
.hasOwnProperty;
for ( var member in members )
{
if ( !hasOwn.call( members, member ) )
{
continue;
}
dest[ member ] = members[ member ];
}
}
return C;
} )( false );
var Foo = Class(
{
__construct: function( name )
{
if ( !name )
{
throw TypeError( "Name required" );
}
this._name = ''+( name );
},
getName: function()
{
return this._name;
}
} );
var SubFoo = Class.extend( Foo,
{
setName: function( name )
{
this._name = ''+( name );
}
} );
var myfoo = new Foo( "Foo" ),
mysub = new SubFoo( "SubFoo" );
myfoo.getName(); // "Foo"
mysub.getName(); // "SubFoo"
mysub.setName( "New Name" );
mysub.getName(); // "New Name"
// parent Foo does not define setName()
myfoo.setName( "Error" ); // TypeError
// our name will be required, since we
// are not extending
new Foo(); // TypeError