consider the following:
foo intends to take the arguments object and rearrange the order, moving arg1 to the position of arg2
function foo (args) {
args[2] = args[1];
args[1] = undefined;
}
bar
calls foo with it's arguments
function bar (a, b, c) {
foo(arguments);
console.log(arguments);
}
I expect the result of the following to be something like { 0: 'hello', 1: undefined, 2: 'world' }
bar('hello', 'world');
However, i get:
{
0: 'hello',
1: undefined,
2: 'world',
3: undefined,
4: undefined,
5: undefined,
6: undefined,
7: undefined,
8: undefined,
9: undefined,
10: undefined,
11: undefined,
12: undefined,
13: undefined,
14: undefined,
15: undefined,
16: undefined,
17: undefined,
18: undefined,
19: undefined
}
I am at a complete loss as to why this happens. Anyone have any ideas?
I'm running this in a node.js environment
The arguments is an object which is local to a function. You can think of it as a local variable that is available with all functions by default except arrow functions in JavaScript. This object (arguments) is used to access the parameter passed to a function. It is only available within a function.
The arguments object is a local variable available within all non-arrow functions. You can refer to a function's arguments inside that function by using its arguments object. It has entries for each argument the function was called with, with the first entry's index at 0 .
Arguments are Passed by Value The parameters, in a function call, are the function's arguments. JavaScript arguments are passed by value: The function only gets to know the values, not the argument's locations. If a function changes an argument's value, it does not change the parameter's original value.
The JavaScript exception "more arguments needed" occurs when there is an error with how a function is called. More arguments need to be provided.
The arguments object
is not an array. It is a list with the internal type Arguments
, with a length
property and getters/setters for properties 0
to len - 1
where len
is the lesser of the number of declared arguments of the function and the number of elements you called the function. Once this object is created, the system will not increase/decrease length
when you operate on its properties, and attempting to set it a length
does not add/remove keys. The getters/setters for properties 0
to len - 1
are indeed aliases to your argument names within the function (i.e., when you set b = 1
you will see arguments[1] === 1
).
What's happened when foo
tries to set args[2]
is addition of an integral property triggers V8 to resize the underlying array storage to 20 elements (it somehow should know that this is an Arguments
type so it can probably set it to a hash property instead). If you set args[20] = 1
it will be resized to 47, args[100] = 1
will resize to 167, but setting args[1026] = 1
will make it a sparse array (but first setting args[1025] = 1
and then args[2048]
does not make it sparse), etc.
After resized, Object.keys
reports all 0
to 19
as properties, so console.log
(which calls util.format
) just prints all of them.
(function (a, b, c) { (function (args) { args[2] = 1; })(arguments); console.log(Object.keys(arguments)); })("hello", "world")
["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"]
This is definitely a V8 bug, although it is very edgy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With