Created
April 28, 2022 01:07
-
-
Save andrewchilds/f93d858d839bf40f0ebe0d2e2e9135f2 to your computer and use it in GitHub Desktop.
Simple, standalone, vanilla implementation of lodash.cloneDeep
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
// Simple implementation of lodash.cloneDeep | |
// Does not clone functions or handle recursive references. | |
export function deepClone(original) { | |
if (original instanceof RegExp) { | |
return new RegExp(original); | |
} else if (original instanceof Date) { | |
return new Date(original.getTime()); | |
} else if (Array.isArray(original)) { | |
return original.map(deepClone); | |
} else if (typeof original === 'object' && original !== null) { | |
const clone = {}; | |
Object.keys(original).forEach(k => { | |
clone[k] = deepClone(original[k]); | |
}); | |
return clone; | |
} | |
return original; | |
} |
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
import deepClone from './deepClone.js'; | |
describe('deepClone', () => { | |
it('creates a deep clone of an object', () => { | |
const original = { | |
foo: { | |
a: 1, | |
b: new Date() | |
}, | |
bar: true, | |
arr: ['a', 'b', { a: 9 }], | |
b: null, | |
c: undefined, | |
d: 123, | |
e: 234.56, | |
f: 'asdfjkh', | |
fn: () => { return true; }, | |
r: /[a-z]/i, | |
}; | |
const clone = deepClone(original); | |
expect(clone).toEqual(original); | |
expect(clone.foo.b).not.toBe(original.foo.b); | |
expect(clone.foo.b.getTime()).toBe(original.foo.b.getTime()); | |
expect(clone.arr).not.toBe(original.arr); | |
expect(clone.arr).toEqual(original.arr); | |
expect(clone.arr[2].a).toBe(original.arr[2].a); | |
expect(clone.fn).toBe(original.fn); | |
expect(clone.r).toEqual(original.r); | |
expect(clone.r).not.toBe(original.r); | |
expect(clone.fn()).toBe(original.fn()); | |
}); | |
it('makes a deep clone of an array', () => { | |
const original = [1, 2, { a: 1, b: 2 }]; | |
let clone = deepClone(original); | |
expect(clone).not.toBe(original); | |
expect(clone).toEqual(original); | |
}); | |
it('makes a clone of an object with object references', () => { | |
const other = { a: 1, b: 2 }; | |
let original = { | |
a: other, | |
b: { | |
a: other | |
} | |
}; | |
const clone = deepClone(original); | |
expect(clone).toEqual(original); | |
other.a = 3; | |
expect(clone.a.a).toBe(1); | |
expect(clone.b.a.a).toBe(1); | |
}); | |
it('makes a clone of a string', () => { | |
let original = 'hello'; | |
const clone = deepClone(original); | |
expect(clone).toBe(original); | |
expect(clone).toEqual(original); | |
original = 'updated'; | |
expect(clone).not.toBe(original); | |
}); | |
it('handles undefined', () => { | |
const original = undefined; | |
const clone = deepClone(original); | |
expect(clone).toBe(original); | |
expect(clone).toEqual(original); | |
}); | |
it('handles null', () => { | |
const original = null; | |
const clone = deepClone(original); | |
expect(clone).toBe(original); | |
expect(clone).toEqual(original); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment