【问题标题】:Why does adding a default parameter value change the behavior when modifying the arguments?为什么在修改参数时添加默认参数值会改变行为?
【发布时间】:2019-04-18 08:32:52
【问题描述】:

第一部分是:

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 中,我发现:

当非严格函数确实包含 rest、default 或 destructured 参数,则参数对象中的值不跟踪 参数的值。相反,它们反映了提供的论点 当函数被调用时

这是来自 MDN 的示例代码:

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

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

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

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

为什么这里有 2 个a?一个在街区,另一个在本地。那么参数a究竟是哪一个呢?另一个a(不是参数)来自哪里?

【问题讨论】:

  • @CertainPerformance 再看一遍
  • 因为一个 'a' 作为参数传递,它被认为是本地的,而另一个是您使用全局的 var 在函数内部创建的。这就是为什么有两个 a。
  • @dharmendra vaishnav 在函数内部创建的也应该被视为局部变量。而在第一节代码中,只有一个a。为什么?

标签: javascript executioncontext


【解决方案1】:

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

至少有一个 rest/default/destructured 参数存在,在这种情况下 no 分配给arguments 的任何索引将导致关联变量的更改,或者有 no 剩余/默认/解构参数,在这种情况下 all 分配给arguments 的任何索引都会导致关联变量发生变化。 p>

arguments 的每个索引都会更改其关联变量,或者不会。所以即使只有b (arguments[1]) 有默认分配,当b 有默认分配时,对arguments[0] 的更改也会导致a 的更改。

为什么这里有 2 个 a?一个在街区,另一个在本地。那么参数a究竟是哪一个呢?另一个a(不是参数)来自哪里?

我很确定 Chrome 调试器只是被混淆了,因为当 a 已经作为参数存在于范围内时,你有 var a。变量出现在“块”部分中时

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

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

a 前面的var,当a 已经存在于范围内时,完全是多余的。

【讨论】:

  • 但是在第二部分代码中,当 b 具有默认赋值时,对 arguments[0] 的更改不会导致对 a 的更改。它们不会一起更改。@CertainPerformance
  • @Chor — 是的。这就是您引用的材料所说的:“当非严格函数确实包含rest、默认或解构参数时,参数对象中的值不跟踪参数的值。相反,它们反映调用函数时提供的参数"
  • 但另一个问题是为什么第二部分代码中存在2个a而在第一部分中只有一个a存在?在图片中,我认为a在本地是初始参数a,它只是保持与arguments[0]相同。然后arguments[0]变为20。由于丢失轨道,这里a仍然保持它的值( 1),但是区块中的a呢?它来自哪里?
  • 当存在与参数同名的变量时,该变量不会影响参数。如果是这样,为什么块中有a变量?
  • @Chor 我很确定 Chrome 调试器只是被混淆了,因为当 a 已经作为参数存在于范围内时,你有 var a。这很可能是一个错误。
猜你喜欢
  • 2016-03-22
  • 1970-01-01
  • 2012-04-30
  • 1970-01-01
  • 2020-05-16
  • 1970-01-01
  • 2013-08-17
  • 2021-12-22
  • 2013-03-30
相关资源
最近更新 更多