Returning 'this' from a method will now return the object instance, not the internal property object
parent
22220cd2da
commit
7427958ec0
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
);
|
||||
} )();
|
||||
|
||||
|
|
Loading…
Reference in New Issue