为什么更改等于 HTML 集合的变量会更改集合的原始值?
Why changing variable equal to a HTML collection changes the original values of the collection?
我看到了一种不同的行为,我无法真正理解为什么会发生这种情况。
本来,让一个变量等于另一个变量后,它只会将一个变量的值复制到另一个变量,但如果我在那之后改变一个变量的值,另一个变量不会受到影响,对吧?如:
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.
这很基础 JavaScript,我知道。但是知道这一点,我不明白为什么它在 HTMLcollection 方面有所不同。
情况如下:
const allLi = document.getElementsByTagName('li');
for (let xis of allLi) {
xis.classList.toggle('highlight');
}
这里我得到一个HTMLcollection,赋值给变量allLi,然后我用for of循环修改它,从而改变了HTMLcollection中的原始值,即参考 li 元素的 class 值。
我的问题是:为什么在这种情况下,如果我通过循环更改变量,我就能够修改 HTML 集合中的原始值?为什么和上一个例子中的a声明一个新值而另一个变量保持不变不一样?
非常感谢。
Javascript 中的对象和数组是通过引用原始对象或数组来存储的。这会导致您观察到的行为。您存储在变量中的所有引用仍然指向同一个对象。
考虑以下因素:
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
保存值 'c' 因为 object1
和 object3
引用对象的同一个实例(实例 1)所以 obect3.prop1
赋值更新 object1
和 object3
变量引用的单个对象的值。
大多数 Web 浏览器控制台都会为您在控制台中引用的任何对象提供一个实例值,让您轻松了解两个变量是否引用同一个对象实例。
例如,Safari 控制台给出以下输出:
> 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
< {}
> object2
< {}
> object3
< {}
以 $ 开头的数字是对象实例编号。
您的第一个示例都使用标量值,并且标量值按值存储。也就是说,如果您创建一个新变量来存储标量值,并将另一个变量的值分配给它,那么您将获得该值,而不是对对象或变量的引用。然后该值独立于原始变量。
我看到了一种不同的行为,我无法真正理解为什么会发生这种情况。 本来,让一个变量等于另一个变量后,它只会将一个变量的值复制到另一个变量,但如果我在那之后改变一个变量的值,另一个变量不会受到影响,对吧?如:
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.
这很基础 JavaScript,我知道。但是知道这一点,我不明白为什么它在 HTMLcollection 方面有所不同。
情况如下:
const allLi = document.getElementsByTagName('li');
for (let xis of allLi) {
xis.classList.toggle('highlight');
}
这里我得到一个HTMLcollection,赋值给变量allLi,然后我用for of循环修改它,从而改变了HTMLcollection中的原始值,即参考 li 元素的 class 值。
我的问题是:为什么在这种情况下,如果我通过循环更改变量,我就能够修改 HTML 集合中的原始值?为什么和上一个例子中的a声明一个新值而另一个变量保持不变不一样?
非常感谢。
Javascript 中的对象和数组是通过引用原始对象或数组来存储的。这会导致您观察到的行为。您存储在变量中的所有引用仍然指向同一个对象。
考虑以下因素:
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
保存值 'c' 因为 object1
和 object3
引用对象的同一个实例(实例 1)所以 obect3.prop1
赋值更新 object1
和 object3
变量引用的单个对象的值。
大多数 Web 浏览器控制台都会为您在控制台中引用的任何对象提供一个实例值,让您轻松了解两个变量是否引用同一个对象实例。
例如,Safari 控制台给出以下输出:
> 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
< {}
> object2
< {}
> object3
< {}
以 $ 开头的数字是对象实例编号。
您的第一个示例都使用标量值,并且标量值按值存储。也就是说,如果您创建一个新变量来存储标量值,并将另一个变量的值分配给它,那么您将获得该值,而不是对对象或变量的引用。然后该值独立于原始变量。