“参数”对象如何在内部工作

How does the "arguments" object work internally?

本文关键字:在内部 工作 对象 参数      更新时间:2023-09-26

如下面的JS代码片段所示,arguments[0]a始终保持相同的值。这在 JS 中是众所周知的,但我仍然很好奇它是如何实现的。

例如,如果aarguments[0]都引用同一个 JS 对象,则它们始终获得更新的值是可以理解的。但这不能解释像 1 这样的原始值的情况。

如果我理解正确,JS总是复制原语的值,这意味着aobject[0]都持有该值的副本。如果是这种情况,aarguments[0]如何始终同步?

function func(a, b) {
  console.log("a = " + a);
  console.log("arguments[0] = " + arguments[0]);
  arguments[0] = 123;
  console.log("a = " + a);
  console.log("arguments[0] = " + arguments[0]);
  a = 123456;
  console.log("a = " + a);
  console.log("arguments[0] = " + arguments[0]);
}
func(1, 2);

这是输出:

>node test.js
a = 1
arguments[0] = 1
a = 123
arguments[0] = 123
a = 123456
arguments[0] = 123456

arguments对象是特殊的,它与Javascript实现存储函数参数的方式挂钩。因此,当您分配给 arguments[n] 时,它实际上会找到用于保存参数变量的内存块,并将您正在分配的值放在那里。在按名称引用参数变量时,也会使用相同的内存位置。

另一种思考方式是每个函数都有一个类似数组的本地arguments对象。当 JS 实现编译函数定义时,它会将所有参数变量替换为对该数组的引用。因此,使用 a 的表达式被编译为使用arguments[0]b被转换为 arguments[1],依此类推。

"参数对象是一个类似数组的对象,对应于传递给函数的参数。 来自 MDN: 参数对象

为了简单起见,想想就知道了。

function func(a, b) {
  // imagine this line of code gets automatically added
  // var arguments = [a, b];
  console.log("a = " + a);
  console.log("arguments[0] = " + arguments[0]);
  arguments[0] = 123;
  console.log("a = " + a);
  console.log("arguments[0] = " + arguments[0]);
  a = 123456;
  console.log("a = " + a);
  console.log("arguments[0] = " + arguments[0]);
}