1
0
Fork 0

Returning 'this' from a method will now return the object instance, not the internal property object

closure/master
Mike Gerwitz 2011-03-10 12:19:39 -05:00
parent 22220cd2da
commit 7427958ec0
2 changed files with 46 additions and 3 deletions

View File

@ -314,6 +314,7 @@ function overrideMethod( super_method, new_method, instCallback )
// __super property
var override = null;
// are we overriding?
if ( new_method )
{
override = function()
@ -330,11 +331,25 @@ function overrideMethod( super_method, new_method, instCallback )
}
else
{
// we are defining a new method
override = function()
{
return super_method.apply(
( instCallback( this ) || this ), arguments
);
var context = instCallback( this ) || this,
retval = undefined
;
// invoke the method
retval = super_method.apply( context, arguments );
// if the value returned from the method was the context that we
// passed in, return the actual instance (to ensure we do not break
// encapsulation)
if ( retval === context )
{
return this;
}
return retval;
};
}

View File

@ -45,6 +45,7 @@ var common = require( './common' ),
'protected protf': protf,
'private privf': privf,
'public getProp': function( name )
{
// return property, allowing us to break encapsulation for
@ -60,6 +61,12 @@ var common = require( './common' ),
{
this[ name ] = value;
},
'public getSelf': function()
{
return this;
},
}),
// instance of Foo
@ -308,3 +315,24 @@ var common = require( './common' ),
);
} )();
/**
* When a method is called, 'this' is bound to the property object containing
* private and protected members. Returning 'this' would therefore be a very bad
* thing. Not only would it break encapsulation, but it would likely have other
* problems down the road.
*
* Therefore, we have to check the return value of the method. If the return
* value is the property object that it was bound to, we need to replace the
* return value with the actual class instance. This allows us to transparently
* enforce encapsulation. How sweet is that?
*/
( function testReturningSelfFromMethodShouldReturnInstanceNotPropObj()
{
assert.deepEqual(
foo.getSelf(),
foo,
"Returning 'this' from a method should return instance of self"
);
} )();