Clone object with:
- Circular references
- Property descriptors
- Symbol properties
- Non-enumerable properties
npm i clone-obj
// or
yarn add clone-obj
Requires node >= 6
const clone = require('clone-obj')
const newObj = clone(obj)
clone-obj
will throw TypeError: Cannot clone undefined or null
when cloning undefined
or null
.
clone-obj
will return primitive values directly.
clone(1) === 1
clone(true) === true
clone('foo') === 'foo'
clone-obj
will use obj.constructor
to create new object.
const arr = []
clone(arr) !== arr
const foo = new Date()
const bar = clone(date)
bar !== foo
bar.getTime() === foo.getTime()
const foo = new Buffer('foo')
const bar = clone(date)
Buffer.isBuffer(bar)
bar !== foo
bar.toString() === foo.toString()
const foo = { a: 1 }
const bar = clone(foo)
bar !== foo
bar.a === foo.a
clone-obj
will auto link circular references with cloned objects.
const foo = {}
foo.self = foo
const bar = clone(bar)
foo !== bar
foo.self !== bar.self
bar === bar.self
console.log(bar) // { self: [Circular] }
clone-obj
respects property descriptors.
const foo = {
get baz () { return this._baz * 2 },
set baz (val) { this._baz = val }
}
const bar = clone(foo)
typeof bar._baz === 'undefined'
isNaN(bar.baz)
bar.baz = 2
bar._baz === 2
bar.baz === 4
const sym = Symbol('foo')
const foo = { [sym]: 1 }
const bar = clone(bar)
bar.hasOwnProperty(sym)
bar[sym] === foo[sym]
const foo = {}
Object.defineProperty(foo, 'baz', {
enumerable: false,
value: 1
})
const bar = clone(foo)
const descriptor = Object.getOwnPropertyDescriptor(bar. 'baz')
descriptor.enumrable === false
Object.keys(bar).length === 0
foo.baz === bar.baz === descriptor.value
const foo = [1, {}]
const bar = clone(foo)
Array.isArray(foo)
foo !== bar
foo.length === bar.length
foo[0] === bar[0]
foo[1] !== bar[1]
const foo = { a: [1] }
const bar = clone(foo)
Array.isArray(bar.a)
foo.a !== bar.a
foo.a.length === bar.a.length