Welcome to the Treehouse Community
The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.
Alex Francis11,515 Points
On spread syntax and multi-dimensional arrays
Exploring more about this (from the teacher's notes):
const brass = [ ['trumpet'], ['tuba'], ['trombone'] ]; const instruments = [...brass]; instruments.shift().shift(); // "trumpet" // Notice how the brass array is also affected by this: brass // [ , ["tuba"], ["trombone"] ]
There seems to be something going on to do with 'shallow' copies, and the difference between copies and references: https://stackoverflow.com/questions/43421704/why-is-a-spread-element-unsuitable-for-copying-multidimensional-arrays
Quite an interesting but confusing topic; I wonder if anyone has a good way of explaining this.
Juan Luna Ramirez8,988 Points
When you refer to an object like an array (either by a variable name or an object property name) you are pointing to the original object/array, often referred to as passing by reference.
// variable alex points to this new array we created const alex = ['alex', 'francis'] // variable person points to thesame array that alex variable points to. // So if we change something using the person variable then we are actually // changing the original array created above. const person = alex person = 'juan' person = 'luna' console.log(alex) // ['juan', 'luna'] oops, not alex anymore
This is simple enough, until the pointer to that original object/array gets passed around and stored in places where you don't know for sure which object/array a variable or property is pointing to.
To prevent this you'll often want to make a copy. There are several ways to do this, including the spread operator, functions (third-party or built-in) or manually duplicating the data.
Again, the tricky bit as before is if you have nested objects/arrays as in the teacher notes example. The spread operator only copies the top level. Which means that any nested objects/array will still point to the original object/array. If you wanted a complete copy you would have to go through all the nested objects/arrays and make a copy of those. This is often referred to a deep clone. This is why developers opt to use a library like lodash. You can use their
cloneDeep function and it will create a deep clone for you! hehe https://lodash.com/docs#cloneDeep. You can also create you own deep clone for this example using the built in
reduce function if you wanted to.
Some comments on the example
const trumpetArray = ['trumpet'] const tubaArray = ['tuba'] const tromboneArray = ['trombone'] const brass = [ trumpetArray, tubaArray, tromboneArray ]; // this is just pointing to the original brass array, so changing anything in // notACopy will result in brass being changed as we've seen before const notACopy = brass // copies ONE level const instruments = [...brass] // to get the same result you can declare a brand new array const brassCopy = [ trumpetArray, tubaArray, tromboneArray ] // So you can add and remove elements from instruments and brassCopy without // affecting bass. brassCopy.shift() console.log(brassCopy) // [["tuba"], ["trombone"]] OK! console.log(brass) // [["trumpet"], ["tuba"], ["trombone"]] YES, untouched! // but as soon as you touch any of the arrays inside, for example the // trumpetArray, then you are changing the original array trumpetArray // is pointing to. instruments.shift() console.log(brass) // [, ["tuba"], ["trombone"]] awww :(