[*] Properties are no longer shared between class instances
- Properties were previously shared on the prototype level, acting as though they were static class properties, which can cause some nasty bugsclosure/master
parent
6efaba7fc5
commit
fe853b505b
28
lib/class.js
28
lib/class.js
|
@ -93,13 +93,23 @@ var extend = ( function( extending )
|
||||||
var result_data = {
|
var result_data = {
|
||||||
abstractMethods: ( base.abstractMethods || [] ).slice()
|
abstractMethods: ( base.abstractMethods || [] ).slice()
|
||||||
};
|
};
|
||||||
util.propCopy( props, prototype, result_data );
|
|
||||||
|
var properties = {};
|
||||||
|
util.propCopy( props, prototype, result_data, {
|
||||||
|
property: function( name, value )
|
||||||
|
{
|
||||||
|
properties[ name ] = value;
|
||||||
|
|
||||||
|
// also add to prototype
|
||||||
|
prototype[ name ] = value;
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
|
||||||
// reference to the parent prototype (for more experienced users)
|
// reference to the parent prototype (for more experienced users)
|
||||||
prototype.parent = base.prototype;
|
prototype.parent = base.prototype;
|
||||||
|
|
||||||
// set up the new class
|
// set up the new class
|
||||||
var new_class = create_ctor( result_data, extending );
|
var new_class = create_ctor( result_data, properties );
|
||||||
|
|
||||||
setup_props( new_class, result_data );
|
setup_props( new_class, result_data );
|
||||||
new_class.prototype = prototype;
|
new_class.prototype = prototype;
|
||||||
|
@ -126,16 +136,26 @@ var extend = ( function( extending )
|
||||||
*
|
*
|
||||||
* @return {Function} constructor
|
* @return {Function} constructor
|
||||||
*/
|
*/
|
||||||
function create_ctor( result_data )
|
function create_ctor( result_data, properties )
|
||||||
{
|
{
|
||||||
// concrete class
|
// concrete class
|
||||||
if ( result_data.abstractMethods.length === 0 )
|
if ( result_data.abstractMethods.length === 0 )
|
||||||
{
|
{
|
||||||
return function()
|
return function()
|
||||||
{
|
{
|
||||||
|
// initialize each of the properties for this instance to
|
||||||
|
// ensure we're not sharing prototype values
|
||||||
|
var value;
|
||||||
|
for ( prop in properties )
|
||||||
|
{
|
||||||
|
// initialize the value with a clone to ensure that they do
|
||||||
|
// not share references (and therefore, data)
|
||||||
|
this[ prop ] = util.clone( properties[ prop ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// call the constructor, if one was provided
|
||||||
if ( this.__construct instanceof Function )
|
if ( this.__construct instanceof Function )
|
||||||
{
|
{
|
||||||
// call the constructor
|
|
||||||
this.__construct.apply( this, arguments );
|
this.__construct.apply( this, arguments );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -135,3 +135,34 @@ assert.throws( function()
|
||||||
});
|
});
|
||||||
}, TypeError, "Cannot override property with a method" );
|
}, TypeError, "Cannot override property with a method" );
|
||||||
|
|
||||||
|
|
||||||
|
var AnotherFoo = Class.extend(
|
||||||
|
{
|
||||||
|
arr: [],
|
||||||
|
obj: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
var Obj1 = new AnotherFoo(),
|
||||||
|
Obj2 = new AnotherFoo();
|
||||||
|
|
||||||
|
Obj1.arr.push( 'one' );
|
||||||
|
Obj2.arr.push( 'two' );
|
||||||
|
|
||||||
|
Obj1.obj.a = true;
|
||||||
|
Obj2.obj.b = true;
|
||||||
|
|
||||||
|
// to ensure we're not getting/setting values of the prototype (=== can also be
|
||||||
|
// used to test for references, but this test demonstrates the functionality
|
||||||
|
// that we're looking to ensure)
|
||||||
|
assert.ok(
|
||||||
|
( ( Obj1.arr[ 0 ] === 'one' ) && ( Obj2.arr[ 0 ] === 'two' ) ),
|
||||||
|
"Multiple instances of the same class do not share array references"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
( ( ( Obj1.obj.a === true ) && ( Obj1.obj.b === undefined ) )
|
||||||
|
&& ( ( Obj2.obj.a === undefined ) && ( Obj2.obj.b === true ) )
|
||||||
|
),
|
||||||
|
"Multiple instances of the same class do not share object references"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue