Why **list** is not a copy of **bookList**?

Why list is not a copy of bookList?

list = bookList; // I assigned the value of bookList for list but when i change list, bookList is changed too.

Please explain this to me!

Thanks!

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1 Safari/605.1.15.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/functional-programming/refactor-global-variables-out-of-functions

Because that’s how variables work: When you say list = bookList, it doesn’t create a copy, it makes list point to exactly the same data as bookList. Or in other words, it makes list an alias (a different name) for bookList.

This is how it works for everything, including numbers and strings, but since they can’t be mutated, you can’t see the aliasing going on. If you want to create a copy of a list, your best bet is to use the spread operator: list = [...bookList]

lets see my exam:

var a = 5;
var b = 6;

a = b; // a = 6; b = 6;
a *= 5; // a = 30; b = 6;

I assign a = b. Value of a is changed (a is a copy of b??)
and then, I changed the value of a, but b value does not change. What happened is here?

pls explain to me!

When you say a = b, you’re assigning a to be an alias of b, that is to say it’s pointing at the same data as b.

When you say a = <some new value>, for example a = 123 you’re saying that a now points to some different data. Since a no longer points to the same data as b, then changes in b won’t be seen in a.

Does that help clear it up?

I got this point. But I’m still stuck array!
How about list? I changed data of list and booklist changed to!

I think a visual explanation is in order, but I lack the graphics skills to execute on it. I’ll give it a try anyway

Starting with list = "foo" and bookList = [1,2,3], you can see how they point to different data (in fact, this kind of variable in other languages is called a pointer but javascript always calls them “variables”)

list----------> "foo"

booklist -----> [1,2,3]

Now, if we assign list = bookList, they point to the same thing:

list ---------+
              |
bookList------+--> [1,2,3]

So when you change to either one of these, it’s the same piece of data that changes. Let’s say you said `list[0] = “xyzzy”

list ---------+
              |
bookList------+--> ["xyzzy",2,3]

Now let’s reassign list to something else, let’s say list = "bar"

list----------> "bar"

booklist -----> ["xyzzy",2,3]

Does that make it any clearer?

1 Like

Awesome @chuckadams! I got it!

Nice!

It is a difference in behaviour on arrays. When you assign a variable that is a number or string to an other variable you are making a copy

Arrays occupy much more space, so when you do that with an array you are copying the reference to the array, not the array itself

There are various ways in which you can copy an array, for example using slice(), concat() or spread operator

1 Like

yup! thanks @ilenia!

There’s no special difference with arrays and anything else. It’s just that non-object datatypes (arrays are special cases of objects) are immutable, so you can’t tell whether they’re aliased or copies.

In fact, javascript will go out of its way to alias identical strings even when you don’t assign them to each other (it’s called “string interning”). Numbers below some maximum value are typically stored “unboxed” and don’t use a pointer at all. Both are invisible optimizations that only concern people writing JS interpreters.

Internally, they are implemented as pointers (plus some type and gc tagging info). They just aren’t visible from the language the way references are. I knew bringing up the p-word was going to confuse the issue.