ECMAScript 变量可能包含两种不同数据类型的值:基本类型值和引用类型值,当从一个变量向另一个变量复制基本类型值和引用类型值时,存在很大的不同。
基本类型的值
如果从一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上。来看一个例子:
let num1 = 8;
let num2 = num1;
在此,num1 中保存的值是 8。当使用 num1 的值来初始化 num2 时,num2 中也保存了值 8。但 num2中的 8 与 num1 中的 8 是完全独立的,该值只是 num1 中 8的一个副本。此后,这两个变量可以参与任何操作而不会相互影响,下图展示复制过程:
制引用类型的值
当从一个变量向另一个变量复制引用类型的值时,同样也会将存储在变量对象中的值复制一份放到 为新变量分配的空间中。不同的是,这个值的副本实际上是一个指针,而这个指针指向存储在堆中的一个对象。复制操作结束后,两个变量实际上将引用同一个对象。因此,改变其中一个变量,就会影响另一个变量,如下面的例子所示:
let obj1 = new Object();
let obj2 = obj1;
obj1.name = "tom";
alert(obj2.name); //"tom"
首先,变量 obj1 保存了一个对象的新实例。然后,这个值被复制到了 obj2 中;换句话说,obj1 和 obj2 都指向同一个对象。这样,当为 obj1 添加 name 属性后,可以通过 obj2 来访问这个属性,因为这两个变量引用的都是同一个对象。下图展示了保存在变量对象中的变量和保存在堆中的对象之间的这种关系。