3

The first section is :

var a = 1;

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

The second section is:

var a = 1;

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

I can understand why in the first section of codes it will finally output 22 and 22 as arguments[0] and a actually both point to the parametera. However, in the second section of codes(which add another parameter b), it finally outputs 22 and 20. I guessed this is to do with the extra parameter b and searched some posts. And in MDN, I found:

When a non-strict function does contain rest, default, or destructured parameters, then the values in the arguments object do not track the values of the arguments. Instead, they reflect the arguments provided when the function was called

And here is an example code from MDN:

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

I can get what it means but things are different in my question.

  1. In the MDN example, it is the a which points to arguments[0] has a default value while in my question it is the b which doesn't point to arguments[0] has a default value. These are 2 different conditions.

  2. I also debugger in the console and found that:

enter image description here

why here we have 2 a? One is in the block while the other is in the local. So which one is actually the parameter a? And where is another a(which is not the parameter) from?

Ivar
  • 6,138
  • 12
  • 49
  • 61
Chor
  • 833
  • 1
  • 5
  • 14
  • @CertainPerformance see it again – Chor Apr 18 '19 at 08:38
  • Because one 'a' is passed as an argument which is considered as local and another you have created inside the function using var which is global. That is why there are two a's. – dharmendra vaishnav Apr 18 '19 at 08:47
  • @dharmendra vaishnav The one which was created inside the function should also be considered as a local variable.And in the first section codes, there is only one `a`.Why? – Chor Apr 18 '19 at 08:51

1 Answers1

1

In the MDN example, it is the a which points to arguments[0] has a default value while in my question it is the b which doesn't point to arguments[0] has a default value. These are 2 different conditions.

Either at least one rest/default/destructured parameter exists, in which case no assignment to any indicies of arguments will result in a change to the associated variable, or there are no rest/default/destructured parameters, in which case all assignments to any indicies of arguments will result in a change to the associated variable.

Either every index of arguments will change its associated variable, or none will. So even though only b (arguments[1]) has a default assignment, when b has a default assignment, changes to arguments[0] will result in changes to a as well.

why here we have 2 a? One is in the block while the other is in the local. So which one is actually the parameter a? And where is another a(which is not the parameter) from?

I'm pretty sure the Chrome debugger is simply confused because you have var a when a already exists in the scope as a parameter. Variables appear in the "block" section when they are either

(1) declared on the top level of a function (with const, let, or var), or

(2) declared with const or let inside a non-function block

The var in front of the a, when a already exists in scope, is completely superfluous.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • But in the second section codes,when b has a default assignment, changes to arguments[0] doesn't result in changes to a .They dont‘t change together.@CertainPerformance – Chor Apr 18 '19 at 09:30
  • 1
    @Chor — Yes. That is what the material you quoted says: "When a non-strict function **does** contain rest, **default**, or destructured parameters, then the values in the arguments object **do not track the values of the arguments**. Instead, they reflect the arguments provided when the function was called" – Quentin Apr 18 '19 at 09:36
  • But another question is why there are 2 `a` existing in the second section codes while in the first seciton there is only one `a` existing?In the picture,I think the `a` in the local is the initial parameter `a`,it just keep the same as arguments[0] at first.And then arguments[0] change to 20.Becasue the losing of track,here the `a` will still keep its value(1),But how about the `a` in the block?Where is it from? – Chor Apr 18 '19 at 09:46
  • When there is a variable which has the same name as the parameter,the variable will not influence the parameter.If so,why there is an `a` variable in the block? – Chor Apr 18 '19 at 09:47
  • @Chor I'm pretty sure the Chrome debugger is simply confused because you have `var a` when `a` already exists in the scope as a parameter. It may well be a bug. – CertainPerformance Apr 18 '19 at 09:54
  • And in the normal condition,there will be only one `a` existing?(If I have declare it as parameter) – Chor Apr 18 '19 at 09:57
  • @Chor That's right: https://jsfiddle.net/jxyb48d6/ There's only one `a`, in the `block` section, when you omit the `var` in front of it. – CertainPerformance Apr 18 '19 at 09:59