可变性
我们现在即将开始真正的编程。 首先还有一个理论要理解。
我们看到对象值可以修改。 千米你的章节讨论的值的类型(如数字,字符串和布尔值)都是不可变的 — 这些类型的值不可能修改。 你可以将它们组合起来并从它们派生新的值,但是当你采用特定的字符串值时,该值将始终保持不变。 里面的文字不能改变。 如果你有一个包含"cat"
的字符串,其他代码不可能修改你的字符串中的一个字符,来使它变成"rat"
。
对象的工作方式不同。你可以更改其属性,使单个对象值在不同时间具有不同的内容。
当我们有两个数字,120 和 120 时,我们可以将它们看作完全相同的数字,不管它们是否指向相同的物理位。 使用对象时,拥有同一个对象的两个引用,和拥有包含相同属性的两个不同的对象,是有区别的。 考虑下面的代码:
let object1 = {value: 10};
let object2 = object1;
let object3 = {value: 10};
console.log(object1 == object2);
// → true
console.log(object1 == object3);
// → false
object1.value = 15;
console.log(object2.value);
// → 15
console.log(object3.value);
// → 10
object1
和object2
绑定持有相同对象,这就是为什么改变object1
会改变object2
的值。 据说他们具有相同的身份。 绑定object3
指向一个不同的对象,它最初包含的属性与object1
相同,但过着单独的生活。
绑定可以是可变的或不变的,但这与它们的值的行为方式是分开的。 即使数值不变,你也可以使用let
绑定来跟踪一个变化的数字,通过修改绑定所指向的值。与之类似,虽然对象的const
绑定本身不可改变,并且始终指向相同对象,该对象的内容可能会改变。
const score = {visitors: 0, home: 0};
// This is okay
score.visitors = 1;
// This isn't allowed
score = {visitors: 1, home: 1};
当你用 JavaScript 的==
运算符比较对象时,它按照身份进行比较:仅当两个对象的值严格相同时才产生true
。 比较不同的对象会返回false
,即使它们属性相同。 JavaScript 中没有内置的“深层”比较操作,它按照内容比较对象,但可以自己编写它(这是本章末尾的一个练习)。