Added deep copy to util.copyTo()
parent
fad503422e
commit
4a0537223b
29
lib/util.js
29
lib/util.js
|
@ -178,13 +178,18 @@ exports.clone = function clone( data, deep )
|
||||||
* destination argument is first to allow extending an object without using the
|
* destination argument is first to allow extending an object without using the
|
||||||
* full-blown class system.
|
* full-blown class system.
|
||||||
*
|
*
|
||||||
* @param {Object} dest destination object
|
* If a deep copy is not performed, all values will be copied by reference.
|
||||||
* @param {Object} src source object
|
*
|
||||||
|
* @param {Object} dest destination object
|
||||||
|
* @param {Object} src source object
|
||||||
|
* @param {boolean} deep perform deep copy (slower)
|
||||||
*
|
*
|
||||||
* @return {Object} dest
|
* @return {Object} dest
|
||||||
*/
|
*/
|
||||||
exports.copyTo = function( dest, src )
|
exports.copyTo = function( dest, src, deep )
|
||||||
{
|
{
|
||||||
|
deep = !!deep;
|
||||||
|
|
||||||
var get, set, data;
|
var get, set, data;
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
|
@ -204,14 +209,18 @@ exports.copyTo = function( dest, src )
|
||||||
|
|
||||||
if ( data.get || data.set )
|
if ( data.get || data.set )
|
||||||
{
|
{
|
||||||
// define the property the slower way (only needed for
|
// Define the property the slower way (only needed for
|
||||||
// getters/setters)
|
// getters/setters). We don't have to worry about cloning in
|
||||||
|
// this case, since getters/setters are methods.
|
||||||
Object.defineProperty( dest, prop, data );
|
Object.defineProperty( dest, prop, data );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// normal copy by reference
|
// normal copy; cloned if deep, otherwise by reference
|
||||||
dest[ prop ] = src[ prop ];
|
dest[ prop ] = ( deep )
|
||||||
|
? exports.clone( src[ prop ], true )
|
||||||
|
: src[ prop ]
|
||||||
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,7 +229,11 @@ exports.copyTo = function( dest, src )
|
||||||
{
|
{
|
||||||
for ( prop in src )
|
for ( prop in src )
|
||||||
{
|
{
|
||||||
dest[ prop ] = src[ prop ];
|
// normal copy; cloned if deep, otherwise by reference
|
||||||
|
dest[ prop ] = ( deep )
|
||||||
|
? exports.clone( src[ prop ], true )
|
||||||
|
: src[ prop ]
|
||||||
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,3 +142,24 @@ var common = require( './common' ),
|
||||||
}, TypeError, "Src parameter is required to be an object" );
|
}, TypeError, "Src parameter is required to be an object" );
|
||||||
} )();
|
} )();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For convenience, let's support a deep copy as well, just in case they don't
|
||||||
|
* want to copy everything by reference.
|
||||||
|
*/
|
||||||
|
( function testCanDeepCopy()
|
||||||
|
{
|
||||||
|
var src = { foo: [ 1, 2, 3 ] },
|
||||||
|
dest = copyTo( {}, src, true );
|
||||||
|
|
||||||
|
// copied values should be equal by value...
|
||||||
|
assert.deepEqual( src.val, dest.val,
|
||||||
|
"Copied values should be comparitively equal with deep copy"
|
||||||
|
);
|
||||||
|
|
||||||
|
// ...but not by reference
|
||||||
|
assert.ok( src.foo !== dest.foo,
|
||||||
|
"Copied values should not be the same object after deep copy"
|
||||||
|
);
|
||||||
|
} )();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue