What is this series about?
Hello all! Welcome to the JavaScript interview questions series. In each post of this series, I will talk abo...
For further actions, you may consider blocking this person and/or reporting abuse
You can also use
JSON.parse(JSON.stringify(obj))
But stringify removes lots of things so you need to write reviver etc. to support instances or constructor refrrences
This example, and the problem statement, are using a nested data structure; not functions or constructors. For the purposes outlined above this is perfectly valid.
Haha! Gary 1 Interviewer 0 😂
This is indeed a nice trick, but do keep in mind that in order for this to work the object must not contain dates, functions, undefined, infinity, nan, regexes, maps, sets, blobs, file lists, image data, sparce / typed arrays or any other complex types. For the majority of the cases though it will do the trick.
If there had been any of the above mentioned, then I would not have recommended my approach.
As you stated this works in the majority of situations and for the examples given.
Some input for a follow-up article or for those who like to get challenged:
Wouldn’t the spread operator work here too ?
I know it technically only clones the top keys but the disconnecting effect of not having a reference to the original is given
Liquid syntax error: 'raw' tag was never closed
honestly thats not really 2021.
thats the old version of the
...
spread operatorLOL!
This clones, but doesn't deep clone. If you mutate an object nested within
source
it'll also mutate the target and vice versa.That will not happen because the first argument is a new object.
To compare:
You can pretty straightforwardly check if that's the case by testing it in the console.
Objects are passed by reference, not value.
When you clone (assign) an object, it doesn't clone the values of objects within, it clones the reference. Which means both objects, the original and the clone are referencing the same nested objects.
It's a tricky and sometimes frustrating quality of JS. Strings, numbers, bools will clone as expected, but objects will continue to reference the same thing.
Think of assigning a DOM element to a variable. The DOM element still exists, and modifying the variable will still affect the DOM. That's because objects are passed by reference!
The DOM part makes me get it.
Watch out for circular references in your recursion.
Preventing endless recursions in the case of circular references can be a bit trickier, specially if you want to reconstruct those same circular structures in the copy of the object. Definitely a good follow-up question, but not something I'd normally expect to be answered flawlessly during an interview, more of a "how'd you go about this?" sort of question.
EDIT: Definitely something I'd expect someone to notice, either in the process of coming up with a simple solution (aka. asking whether loops need to be considered), or at least when asked to find possible flaws in their solution.
Object.prototype.toString.call(source[key]) === "[object Object]" can be used to identify if the value is an Object and rest can be directly put in the resulting object.
if the source input is as below:
let source = {
a: 10,
b: 20,
c: [1,2,3,4]
}
the output will be. here the c was n array and it got converted to object.
{
"a": 10,
"b": 20,
"c": {
"0": 1,
"1": 2,
"2": 3,
"3": 4
}
}
If we use Object.prototype.toString.call(source[key]) === "[object Object]" it will clone properly.
typeof null === "object", so you have to add a special clause for that :)
My first thought was wouldn’t I just use Object.assign, is that a valid answer?
Object.assign
is equivalent to object spread and only copies the top level keys of an objectstackoverflow.com/questions/122102...
Not in the provided sample, but if you are deep cloning you might want to consider if one of the values is an array and also if the values contained in the array are object themselves