Created
June 23, 2018 09:06
-
-
Save kxtxr/26bf36e446c9db0a8bfb70321f27dc4c to your computer and use it in GitHub Desktop.
Deep clone an object
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @type {Function} | |
*/ | |
var toString = Object.prototype.toString; | |
/** | |
* @description Clones an object using deep copy | |
* | |
* @param {Object} sourceObject Object to clone | |
* @returns {Object} Cloned object. | |
* @throws {Error} | |
*/ | |
function deepClone(sourceObject) { | |
if (!sourceObject || typeof sourceObject != "object") { | |
// Any non-object (Boolean, String, Number), null, undefined, NaN | |
return sourceObject; | |
} | |
// Honor native/custom clone methods | |
if (sourceObject.clone && toString.call(sourceObject.clone) == "[object Function]") { | |
return sourceObject.clone(deep); | |
} | |
// Date | |
if (sourceObject instanceof Date) { | |
var clone = new Date(); | |
clone.setTime(sourceObject.getTime()); | |
return clone; | |
} | |
// Array | |
if (sourceObject instanceof Array) { | |
var clone = []; | |
for (var i = 0, len = sourceObject.length; i < len; i++) { | |
clone[i] = deepClone(sourceObject[i]); | |
} | |
return clone; | |
} | |
// RegExp | |
if (toString.call(sourceObject) == "[object RegExp]") { | |
return new RegExp(sourceObject); | |
} | |
// DOM elements | |
if (sourceObject.nodeType && toString.call(sourceObject.cloneNode) == "[object Function]") { | |
// Deep clone the node | |
return sourceObject.cloneNode(true); | |
} | |
if (sourceObject instanceof Object) { | |
var clone = {}; | |
for (var key in sourceObject) { | |
if (sourceObject.hasOwnProperty(key)) clone[key] = deepClone(sourceObject[key]); | |
} | |
return clone; | |
} | |
throw new Error("Unable to clone this object."); | |
} | |
if (typeof module === 'object' && module.exports) { | |
module.exports = deepClone | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* global describe, it */ | |
var assert = require('assert'); | |
var deepClone = require('./deepClone'); | |
describe('deepClone', function() { | |
var testObj; | |
var clonedObj; | |
before( function() { | |
testObj = { | |
a: 2, | |
b: { | |
c: "A Name", | |
d: function(param) { | |
return param | |
}, | |
e: { | |
f: 4, | |
g: 67, | |
h: [2, 6, Number] | |
}, | |
g: false | |
}, | |
j: new Date(), | |
k: /^[0-9]/ | |
}; | |
}); | |
beforeEach( function() { | |
clonedObj = deepClone(testObj); | |
}); | |
it('should clone testObj', function() { | |
assert.deepEqual(testObj, clonedObj); | |
}); | |
it('should not be \'equal\'', function() { | |
clonedObj.a = 3; | |
assert.notDeepEqual(testObj, clonedObj); | |
}); | |
it('should not be \'equal\'', function() { | |
clonedObj.b.g = true; | |
assert.notDeepEqual(testObj, clonedObj); | |
}); | |
it('should not be \'equal\'', function() { | |
clonedObj.b.e.h[0] = 1; | |
assert.notDeepEqual(testObj, clonedObj); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage
Test