3
\$\begingroup\$

My goal was to create a single-line function that produces a deep copy of a javascript object.

Requirements:

  • Executable on a single line without the use of semicolons (exception: last character of the line)
  • Nested objects should not be references to the originals

Function:

let copiedObjct = (copy = (obj) => (Object.keys(obj).reduce((v, d) => Object.assign(v, {[d]: (obj[d].constructor === Object) ? copy(obj[d]) : obj[d]}), {})))(obj);

Usage (expanded):

let obj = { /*...*/ }
let copiedObjct = (copy = (obj) => (
 Object.keys(obj).reduce((v, d) => Object.assign(v, {
 [d]: (obj[d].constructor === Object) ? copy(obj[d]) : obj[d]
 }), {})
))(obj);

My questions are:

  1. Is this code efficient?
  2. Are there any reasons this shouldn't be used in the wild?
  3. Is there a way I can make it shorter?
asked Jun 19, 2018 at 18:08
\$\endgroup\$
3
  • 1
    \$\begingroup\$ JSON.parse(JSON.stringify(obj)) with some caveats may work for you. \$\endgroup\$ Commented Jun 20, 2018 at 8:56
  • \$\begingroup\$ Is there a way I can make it shorter?: 163b -> 144b: let copiedObjct=(copy=(obj)=>(Object.keys(obj).reduce((v,d)=>Object.assign(v,{[d]:(obj[d].constructor===Object)?copy(obj[d]):obj[d]}),{})))(obj) \$\endgroup\$ Commented Jun 20, 2018 at 9:45
  • 1
    \$\begingroup\$ const copy = obj => typeof obj == 'object' ? Object.entries(obj).reduce((r, [k, v]) => (r[k] = copy(v), r), {}) : obj, still somewhat readable... though Joseph really has the right answer here. \$\endgroup\$ Commented Jun 21, 2018 at 2:43

1 Answer 1

3
\$\begingroup\$

Is this code efficient?

Probably... not.

Efficiency can mean different things. Efficiency could mean "fast running code" or "use the least amount of memory" - this can only be determined by running the code through a profiler. Efficiency could also mean "I can use it easily" or "works reliably" or "handles edge cases well" - this can only be determined by having other people use it.

Are there any reasons this shouldn't be used in the wild?

Yes.

Does the code really run on a variety of objects? What if I put things like Arrays, Dates, RegExps, Maps, Sets, etc. in my object? Does it handle circular references? This is a naive implementation of deep-copy which is fine in small apps and prototypes where you know what the data looks like. But in more general cases, this will probably not hold.

If you'd like to see how a general-purpose deep-copy function looks like, see how jQuery.extend or lodash.assign is implemented.

Is there a way I can make it shorter?

Wrong question. Code size is irrelevant in JS, you have minifiers for that.

answered Jun 20, 2018 at 3:10
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.