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
Let
len
be the number of elements in args.Let
indx
=len - 1
.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
:)
- Add
name
as an element of the listmappedNames
.
- Let
g
be the result of calling theMakeArgGetter
abstract operation with argumentsname
andenv
.
- Let
p
be the result of calling theMakeArgSetter
abstract operation with argumentsname
andenv
.
- Call the [[DefineOwnProperty]] internal method of
map
passing ToString(indx
), the Property Descriptor {[[Set]]:p
, [[Get]]:g
, [[Configurable]]:true
}, andfalse
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()
anda(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, orif 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.