[*] 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 = {
|
||||
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)
|
||||
prototype.parent = base.prototype;
|
||||
|
||||
// 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 );
|
||||
new_class.prototype = prototype;
|
||||
|
@ -126,16 +136,26 @@ var extend = ( function( extending )
|
|||
*
|
||||
* @return {Function} constructor
|
||||
*/
|
||||
function create_ctor( result_data )
|
||||
function create_ctor( result_data, properties )
|
||||
{
|
||||
// concrete class
|
||||
if ( result_data.abstractMethods.length === 0 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
// call the constructor
|
||||
this.__construct.apply( this, arguments );
|
||||
}
|
||||
};
|
||||
|
|
|
@ -135,3 +135,34 @@ assert.throws( function()
|
|||
});
|
||||
}, 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