diff --git a/lib/class.js b/lib/class.js index a746417..36778f3 100644 --- a/lib/class.js +++ b/lib/class.js @@ -776,8 +776,6 @@ function attachPropInit( prototype, properties, members ) { util.defineSecureProp( prototype, '__initProps', function() { - var inst_props = class_instance[ this.__iid ]; - // first initialize the parent's properties, so that ours will overwrite // them var parent_init = prototype.parent.__initProps; @@ -786,6 +784,10 @@ function attachPropInit( prototype, properties, members ) parent_init.call( this ); } + var inst_props = propobj.createPropProxy( + this, class_instance[ this.__iid ], properties[ 'public' ] + ); + propobj.setup( this, inst_props, properties, members ); }); } diff --git a/lib/propobj.js b/lib/propobj.js index 5f9d59b..a36ff01 100644 --- a/lib/propobj.js +++ b/lib/propobj.js @@ -38,25 +38,6 @@ exports.setup = function( base, dest, properties, members ) // initialize the value with a clone to ensure that they do // not share references (and therefore, data) base[ prop ] = util.clone( prop_pub[ prop ] ); - - ( function( prop ) - { - var inst = this; - - // public properties, when set internally, must forward to the - // actual variable - dest.__defineSetter__( prop, function( val ) - { - inst[ prop ] = val; - } ); - - // since we're defining a setter, we'll need to define a getter - // to return the value, or we'll simply return undefined - dest.__defineGetter__( prop, function() - { - return inst[ prop ]; - } ); - } ).call( base, prop ); } var methods_protected = members[ 'protected' ], @@ -77,5 +58,54 @@ exports.setup = function( base, dest, properties, members ) { dest[ prop ] = util.clone( prop_prot[ prop ] ); } -} +}; + + +/** + * Creates a proxy for all given properties to the given base + * + * The proxy uses getters/setters to forward all calls to the base. The + * destination object will be used as the proxy. All properties within props + * will be used proxied. + * + * To summarize: for each property in props, all gets and sets will be forwarded + * to base. + * + * @param {Object} base object to proxy to + * @param {Object} dest object to treat as proxy (set getters/setters on) + * @param {Object} props properties to proxy + * + * @return {Object} returns dest + */ +exports.createPropProxy = function( base, dest, props ) +{ + var hasOwn = Object.prototype.hasOwnProperty; + + for ( prop in props ) + { + if ( !( hasOwn.call( props, prop ) ) ) + { + continue; + } + + ( function( prop ) + { + // public properties, when set internally, must forward to the + // actual variable + dest.__defineSetter__( prop, function( val ) + { + base[ prop ] = val; + } ); + + // since we're defining a setter, we'll need to define a getter + // to return the value, or we'll simply return undefined + dest.__defineGetter__( prop, function() + { + return base[ prop ]; + } ); + } ).call( null, prop ); + } + + return dest; +};