Changing JavaScript function's parameter value using arguments array not working

Assigning to arguments indicies will only change the associated argument value (let's call it the n-th argument) if the function was called with at least n arguments. The arguments object's numeric-indexed properties are essentially setters (and getters):

http://es5.github.io/#x10.6

Italics in the below are my comments on how the process relates to the question:

(Let) args (be) the actual arguments passed to the [[Call]] internal method

  1. Let len be the number of elements in args.

  2. Let indx = len - 1.

  3. Repeat while indx >= 0, (so, the below loop will not run when no arguments are passed to the function:)

(assign to the arguments object being created, here called map:)

    1. Add name as an element of the list mappedNames.
    1. Let g be the result of calling the MakeArgGetter abstract operation with arguments name and env.
    1. Let p be the result of calling the MakeArgSetter abstract operation with arguments name and env.
    1. Call the [[DefineOwnProperty]] internal method of map passing ToString(indx), the Property Descriptor {[[Set]]: p, [[Get]]: g, [[Configurable]]: true}, and false as arguments.

So, if the function is invoked with no arguments, there will not be a setter on arguments[0], so reassigning it won't change the parameter at index 0.

The same sort of thing occurs for other indicies as well - if you invoke a function with 1 parameter, but the function accepts two parameters, assigning to arguments[1] will not change the second parameter, because arguments[1] does not have a setter:

function fn(a, b) {
  arguments[1] = 'bar';
  console.log(b);
}
fn('foo');

So

a() and a(undefined) are the same thing right?

is not the case, because the second results in an arguments object with a setter and a getter on index 0, while the first doesn't.

Note that this odd interaction between the arguments and the function parameters is only present in sloppy mode. In strict mode, changes to arguments won't have any effect on the value an individual argument identifier contains:

'use strict';
function a(b) {
  arguments[0] = 2;
  return b;
}
console.log(a(1)); //returns 1


ECMA 262 9.0 2018 describes this behaviour in 9.4.4 Arguments Exotic Objects with

NOTE 1:

The integer-indexed data properties of an arguments exotic object whose numeric name values are less than the number of formal parameters of the corresponding function object initially share their values with the corresponding argument bindings in the function's execution context. This means that changing the property changes the corresponding value of the argument binding and vice-versa. This correspondence is broken if such a property is deleted and then redefined or if the property is changed into an accessor property. If the arguments object is an ordinary object, the values of its properties are simply a copy of the arguments passed to the function and there is no dynamic linkage between the property values and the formal parameter values.

In short,

  • if in 'sloppy mode', then all arguments are mapped to their named variables, if the length correspond to the given parameter, or

  • if in 'strict mode', then the binding is lost after handing over the arguments.

This is only readable in an older version of ECMA 262 7.0 2016. It describes this behaviour in 9.4.4 Arguments Exotic Objects with

Note 1:

For non-strict functions the integer indexed data properties of an arguments object whose numeric name values are less than the number of formal parameters of the corresponding function object initially share their values with the corresponding argument bindings in the function's execution context. This means that changing the property changes the corresponding value of the argument binding and vice-versa. This correspondence is broken if such a property is deleted and then redefined or if the property is changed into an accessor property. For strict mode functions, the values of the arguments object's properties are simply a copy of the arguments passed to the function and there is no dynamic linkage between the property values and the formal parameter values.