Skip to content

值和引用

Published:
var foo = { bar: 1 };
var arr1 = [1, 2, foo];
var arr2 = arr1.slice(1);

arr2[0]++;
arr2[1].bar++;

foo.bar++;

arr1[2].bar++;

console.log(arr1[1] === arr2[0]);
console.log(arr1[2] === arr2[1]);
console.log(foo.bar);

解析

  1. 第一条语句

首先在内存中创建一块内存空间,存放一个 { bar: 1 } 的对象,假设该内存地址为 A,并且把 A 作为变量 foo 的引用地址,有:

MemoryAddress
{ bar: 1 }A
MemoryVariables
Afoo
  1. 第二条语句

同样地,在内存中存放1、2,并且引用foo的内存地址,假设该数组的内存地址为 B,有:

MemoryAddress
[1, 2, A]B
  1. 第三条语句

通过 arr1 的地址找到这个数组内容,slice 方法会返回一个新的数组,所以同样地,在内存中存放 2、foo 的引用地址,假设该数组的内存地址为 C,有:

MemoryAddress
[2, A]C

当依次改变后:

arr2[0]++; // 通过地址 C 找到 [2, A],此时第一项为3
arr2[1].bar++; // 通过地址 C 找到引用地址 A 找到 bar,此时 bar 的值为2
foo.bar++; // 通过引用地址 A 找到 { bar: 2 },此时 bar 的值为3
arr1[2].bar++; // 通过地址 B 找到引用地址 A 找到 bar,此时 bar 的值为4

最终结果为:

arr1[1] === arr2[0]; // 2 !== 3 return false
arr1[2] === arr2[1]; // 引用地址都为 A return true
foo.bar; // 4

参考资料