Here, person is an object and therefore a so-called reference type. Please note that it holds properties that in turn have primitive values. This doesn’t affect the object being a reference type though. And you could of course also have nested objects or arrays inside the person object.

The hobbies array is also a reference type - in this case, it holds a list of strings. A string is a primitive value/ type as you learned but this doesn’t affect the array. Arrays are always reference types.

Cool, we got two different types of values. What’s the idea behind all of that?

It’s related to memory management.

Behind the scenes, JavaScript of course has to store the values you assign to properties or variable in memory.

JavaScript knows two types of memory: The Stack and the Heap. You can dive much deeper if you want to.

Here’s a super-short summary: The stack is essentially an easy-to-access memory that simply manages its items as a - well - stack. Only items for which the size is known in advance can go onto the stack. This is the case for numbers, strings, booleans.

The heap is a memory for items of which you can’t pre-determine the exact size and structure. Since objects and arrays can be mutated and change at runtime, they have to go into the heap therefore.

Obviously, there’s more to it but this rough differentiation will do for now.

For each heap item, the exact address is stored in a pointer which points at the item in the heap. This pointer in turn is stored on the stack. That will become important in a second.
Okay, so we got different memories. But how does that make a difference to us, the developer?

Because you never copied the person object itself to newPerson. You only copied the pointer! It still points at the same address in memory though. Hence changing newPerson.name also changes person.name because newPerson points at the exactly same object!

This is really important to understand! You’re pointing at the same object, you didn’t copy the object.

It’s the same for arrays.

var hobbies =['Sports','Cooking']var copiedHobbies = hobbies
copiedHobbies.push('Music')
console.log(hobbies[2])// What does this line print?

1) Use the slice() method

slice() is a standard array method provided by JavaScript. You can check out its full documentation here.

var hobbies =['Sports','Cooking']var copiedHobbies = hobbies.slice()

It basically returns a new array which contains all elements of the old element, starting at the starting index you passed (and then up to the max number of elements you defined).
If you just call slice(), without arguments, you get a new array with all elements of the old array.

Here’s on super-important thing to note though: You’re not creating deep clones with either approach!

If you cloned array contains nested arrays or objects as elements or if your object contains properties that hold arrays or other objects, then these nested arrays and objects will not have been cloned!

You still have the old pointers, pointing to the old nested arrays/ objects!

You’d have to manually clone every layer that you plan on working with. If you don’t plan on changing these nested arrays or objects though, you don’t need to clone them.