Why reassigning arguments doesn't work with arguments that have default values?

Viewed 98

I have a really weird question that I don't know how it occurs.

When I reassign an argument with arguments[0] = 42. The arguments[0] and the first argument a are both 42. Which is expected.

function foo(a, b, c) {
  arguments[0] = 42;
  console.log(a, arguments[0]);
}

foo(1, 2, 3);

But when I tried with a function that has an argument with a default value, the first value a doesn't get reassigned anymore. Can someone explain this discrepancy?

function foo(a, b, c = 3) {
  arguments[0] = 42;
  console.log(a, arguments[0]);
}

foo(1, 2, 3);

2 Answers

There is a note in the spec about this - you only get a mapped arguments object when you're not using ES6+ syntax (or in strict mode) in your function declaration (emphasis mine):

NOTE: A mapped argument object is only provided for non-strict functions that don't have a rest parameter, any parameter default value initializers, or any destructured parameters

As you are using a default parameter, your arguments object doesn't get mapped, just like it doesn't when you're in strict-mode:

function foo(a, b, c) {
  "use strict";
  arguments[0] = 42;
  console.log(a, arguments[0]);
}

foo(1, 2, 3); // 1 42

The arguments object - JavaScript | MDN -> Rest, default, and destructured parameters

In strict-mode code, the arguments object behaves the same whether or not a function is passed rest, default, or destructured parameters. That is, assigning new values to variables in the body of the function will not affect the arguments object. Nor will assigning new variables to the arguments object affect the value of variables.

...

Non-strict functions that are passed only simple parameters (that is, not rest, default, or restructured parameters) will sync the value of variables new values in the body of the function with the arguments object, and vice versa.

...

Conversely, non-strict functions that are passed rest, default, or destructured parameters will not sync new values assigned to argument variables in the function body with the arguments object. Instead, the arguments object in non-strict functions with complex parameters will always reflect the values passed to the function when the function was called (this is the same behavior as exhibited by all strict-mode functions, regardless of the type of variables they are passed)

Related