Extended clone to also copy functions by using clone( some_data, true).
This commit is contained in:
parent
4c2d3e50c3
commit
76982a8976
2 changed files with 48 additions and 11 deletions
|
@ -74,41 +74,49 @@ function difference(object1, object2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// clone, just data, no instances of objects
|
// clone, just data, no instances of objects
|
||||||
function clone(item) {
|
function clone(item, full) {
|
||||||
if (!item) { return item; }
|
if (!item) { return item }
|
||||||
|
|
||||||
// ignore certain objects
|
// ignore certain objects
|
||||||
var acceptedInstances = [ 'Object', 'Number', 'String', 'Boolean', 'Array' ];
|
var acceptedInstances = [ 'Object', 'Number', 'String', 'Boolean', 'Array' ]
|
||||||
|
if (full) {
|
||||||
|
acceptedInstances.push( 'Function' )
|
||||||
|
}
|
||||||
if (item && item.constructor) {
|
if (item && item.constructor) {
|
||||||
if (!_.contains(acceptedInstances, item.constructor.name)) {
|
if (!_.contains(acceptedInstances, item.constructor.name)) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var result;
|
|
||||||
// copy array
|
// copy array
|
||||||
|
var result;
|
||||||
if ( _.isArray(item) ) {
|
if ( _.isArray(item) ) {
|
||||||
result = [];
|
result = []
|
||||||
item.forEach(function(child, index, array) {
|
item.forEach(function(child, index, array) {
|
||||||
result[index] = clone( child );
|
result[index] = clone( child, full )
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy function
|
||||||
|
else if ( _.isFunction(item) ) {
|
||||||
|
result = item.bind({})
|
||||||
|
}
|
||||||
|
|
||||||
// copy object
|
// copy object
|
||||||
else if ( _.isObject(item) ) {
|
else if ( _.isObject(item) ) {
|
||||||
result = {};
|
result = {}
|
||||||
for(var key in item) {
|
for(var key in item) {
|
||||||
if (item.hasOwnProperty(key)) {
|
if (item.hasOwnProperty(key)) {
|
||||||
result[key] = clone(item[key])
|
result[key] = clone( item[key], full )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy others
|
// copy others
|
||||||
else {
|
else {
|
||||||
result = item;
|
result = item
|
||||||
}
|
}
|
||||||
return result;
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// taken from http://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript
|
// taken from http://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript
|
||||||
|
|
|
@ -486,10 +486,12 @@ test( "clone", function() {
|
||||||
var source = [
|
var source = [
|
||||||
{ name: 'some name' },
|
{ name: 'some name' },
|
||||||
{ name: 'some name2' },
|
{ name: 'some name2' },
|
||||||
|
{ fn: function() { return 'test' } },
|
||||||
]
|
]
|
||||||
var reference = [
|
var reference = [
|
||||||
{ name: 'some name' },
|
{ name: 'some name' },
|
||||||
{ name: 'some name2' },
|
{ name: 'some name2' },
|
||||||
|
{ fn: undefined },
|
||||||
]
|
]
|
||||||
var result = clone( source )
|
var result = clone( source )
|
||||||
|
|
||||||
|
@ -498,6 +500,33 @@ test( "clone", function() {
|
||||||
|
|
||||||
deepEqual( result, reference, 'clone' );
|
deepEqual( result, reference, 'clone' );
|
||||||
|
|
||||||
|
|
||||||
|
// full test
|
||||||
|
var source = [
|
||||||
|
{ name: 'some name' },
|
||||||
|
{ name: 'some name2' },
|
||||||
|
{ fn: function a() { return 'test' } },
|
||||||
|
]
|
||||||
|
var reference = [
|
||||||
|
{ name: 'some name' },
|
||||||
|
{ name: 'some name2' },
|
||||||
|
{ fn: function a() { return 'test' } },
|
||||||
|
]
|
||||||
|
var result = clone( source, true )
|
||||||
|
|
||||||
|
// modify source later, should not have any result
|
||||||
|
source[0].name = 'some new name'
|
||||||
|
source[2].fn = 'some new name'
|
||||||
|
|
||||||
|
deepEqual( result[0], reference[0], 'clone full' );
|
||||||
|
deepEqual( result[1], reference[1], 'clone full' );
|
||||||
|
|
||||||
|
equal( typeof reference[2].fn, 'function')
|
||||||
|
equal( typeof result[2].fn, 'function')
|
||||||
|
|
||||||
|
equal( reference[2].fn(), 'test')
|
||||||
|
equal( result[2].fn(), 'test')
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// diff
|
// diff
|
||||||
|
|
Loading…
Reference in a new issue