There's a different behaviour that I see that I can't really understand exactly why this happens. Originally, after making a variable equal to another, it will only copy the value of one variable to another, but if I change the value of a variable after that, the other variable won't be affected, right? As in:
let a = 3
let b = 5
b = a
//here the variable b, that was 5 will become the same as the variable a, becoming 3.
a = 10
//now, if I change the value in a to 10, b will still have the value of 3.
That's pretty basic JavaScript, I know. But knowing that, I can't understand why it's different when it comes to HTMLcollection.
Here is the situation:
const allLi = document.getElementsByTagName('li');
for (let xis of allLi) {
xis.classList.toggle('highlight');
}
Here I got a HTMLcollection and assigned it to the variable allLi, and then I used a for of loop to modify it, thus changing the original values in the HTMLcollection, that reefer to the class values of the li elements.
My question is: why in this case if I change a variable through the loop I'm able to modify the original values in the HTMLcollection? Why it's different of when I declare a new value to a in the previous example and the other variable keeps unchanged?
Thank you very much.
Objects and arrays in Javascript are stored by reference to the original object or array. This leads to the behaviour you have observed. All the references you are storing in variables still point to the same object.
Consider the following:
let object1 = new Object // Reference to object instance 1
let object2 = new Object // Reference to object instance 2
let object3 = object1 // Reference to object instance 1
object1.prop1 = 'a'
object2.prop1 = 'b'
object3.prop1 = 'c'
object1.prop1 // 'c'
object2.prop1 // 'b'
object3.prop1 // 'c'
object1.prop1
holds the value 'c' because both object1
and object3
reference the same instance of the object (instance 1) so the obect3.prop1
assignment updates the value of the single object referred to by both object1
and object3
variables.
Most web browser consoles will give you an instance value for any object that you reference in the console, easily allowing you to know if two variables are referencing the same instance of an object.
For instance, the Safari console gives the following output:
> let object1 = new Object // Reference to object instance 1
let object2 = new Object // Reference to object instance 2
let object3 = object1 // Reference to object instance 1
< undefined
> object1
< {} $1
> object2
< {} $2
> object3
< {} $1
The numbers preceded by a $ being the object instance number.
Your first examples all use scalar values, and scalar values are stored by value. That is, if you create a new variable to store a scalar value, and assign to it the value of another variable then that is what you get - the value, and not a reference to an object or variable. This value then becomes independent of the original variable.