javascript “arguments”对象内部是如何工作的?

twh00eeo  于 2023-02-11  发布在  Java
关注(0)|答案(3)|浏览(114)

如下面的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
fivyi3re

fivyi3re1#

arguments对象很特殊,它与Javascript实现存储函数参数的方式挂钩。因此,当你赋值给arguments[n]时,它实际上会找到用于保存参数变量的内存块,并将你赋值的值放在那里。当按名称引用参数变量时,也会使用相同的内存位置。
另一种思考方式是,每个函数都有一个类似于arguments数组的局部对象,当JS实现编译函数定义时,它会将所有参数变量替换为对该数组的引用,因此使用a的表达式会像使用arguments[0]一样被编译,b会被转换为arguments[1],依此类推。

0vvn1miw

0vvn1miw2#

arguments对象是与传递给函数的参数相对应的类数组对象。”来自MDN: Arguments object
为了简单起见,只要想想。

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]);
}
06odsfpq

06odsfpq3#

在JavaScript中,函数参数被视为局部变量。在您提供的示例中,a参数在调用函数时被赋值为1
arguments对象是一个类似数组的对象,它包含传递给函数的所有参数。
arguments[0]是对传递给函数的第一个参数的引用,在本例中为1
在JavaScript中,当你给一个变量赋一个像1这样的基元值时,这个值会被复制并存储到变量中,这意味着aarguments[0]分别拥有一个1值的副本。
但是,当您为arguments[0]赋值时,这会更新存储在arguments对象中的值,而arguments对象又会更新a的值,因为aarguments[0]引用相同的值,这是因为在JavaScript中,变量是通过引用传递的。
当您将引用赋给对象或将数组赋给变量时,变量和arguments对象都引用内存中的同一对象。
当你通过其中一个引用修改对象时,它会反映在两个引用中,所以总的来说,你观察到的行为是由于在JavaScript中,变量是通过引用传递的,而arguments对象是对传递给函数的参数的引用。

相关问题