为什么在修改参数时添加默认参数值会改变行为?

时间:2019-04-18 08:32:53

标签: javascript executioncontext

第一部分是:

var a = 1;

function fn2(a) {
  arguments[0] = 20;
  var a = 22;
  console.log(a);
  console.log(arguments[0]);
}
fn2(a);

第二部分是:

var a = 1;

function fn2(a, b = 100) {
  arguments[0] = 20;
  var a = 22;
  console.log(a);
  console.log(arguments[0]);
}
fn2(a);

我可以理解为什么在代码的第一部分中它最终会输出22和22,因为arguments[0]a实际上都指向参数a。 但是,在代码的第二部分(添加另一个参数b)中,它最终输出22和20。我猜想这与多余的参数b有关,并搜索了一些帖子。在MDN中,我发现:

  

当非严格函数确实包含休息,默认或变形   参数,则arguments对象中的值不会跟踪   参数值。相反,它们反映了提供的参数   该函数何时被调用

这是MDN的示例代码:

function func(a = 55) { 
  arguments[0] = 99; // updating arguments[0] does not also update a
  console.log(a);
}
func(10); // 10

我能理解它的意思,但是我的问题有所不同。

  1. 在MDN示例中,指向a的是arguments[0]具有默认值,而在我的问题中,指向b的不是{ {1}}具有默认值。这是两个不同的条件。

  2. 我也在控制台中调试器,发现:

enter image description here

为什么我们这里有2个arguments[0]?一个在街区,而另一个在街区。那么,参数a实际上是哪个?还有另一个a(不是参数)从哪里来?

1 个答案:

答案 0 :(得分:1)

  

在MDN示例中,指向参数[0]的a是默认值,而在我的问题中,指向参数[0]的b是默认值。这是两个不同的条件。

至少存在一个 个rest / default / destructed参数,在这种情况下,给所有arguments的索引 no 赋值都会导致对相关变量,或者没有 个rest / default / destructed参数,在这种情况下,对所有arguments指标的 all 赋值都会导致相关变量的更改变量。

arguments的每个索引都将更改其关联的变量,否则将不会更改。因此,即使只有barguments[1])具有默认分配,但当b具有默认分配时,对arguments[0]的更改将导致对a的更改,如下所示:好吧。

  

为什么我们这里有2个?一个在街区,而另一个在街区。那么,参数a实际上是哪个?还有另一个(不是参数)来自哪里?

我非常确定Chrome调试器只是感到困惑,因为当var a作为参数已经存在于范围中时,您拥有a。变量之一出现在“块”部分

(1)在函数的顶层(用constletvar声明),或

(2)在非功能块中用constlet声明

如果var已经存在,则a前面的a是完全多余的。