Is this legal? And does it work in all browsers?
function func1(a, b, c) {
//b == 2 here
change_em(arguments);
//b should equal 3 here
}
function change_em(args) {
args[0] = 6;
args[1]++;
args[2] = [];
}
func1('foo', 2);
If you are wondering, I need to adjust the arguments in a function. A macro would be perfect, except javascript doesn't have one. Doing it properly, i.e. passing the variables to a function, then returning them in an object, and then extracting them in the caller would be almost as much code as just copy/pasting the adjuster function.
Passing a function as an argument to the function is quite similar to the passing variable as an argument to the function. so variables can be returned from a function.
Some functions work by modifying the values of their arguments. This may be done to pass more than one value back to the calling routine, or because the return value is already being used in some way.
When you call a function in JavaScript, you can pass in any number of arguments, regardless of what the function declaration specifies. There is no function parameter limit. In the above function, if we pass any number of arguments, the result is always the same because it will take the first two parameters only.
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.
It is valid under EcmaScript 3 and EcmaScript 5 non-strict, but it is not valid under EcmaScript 5 strict mode. It works in all modern browsers and most old ones. It should not work in strict mode such as when run in Firefox 5 with a "use strict"
directive.
From the EcmaScript 5 spec section 10.6.11.c.ii
10.6 Arguments Object
...
If strict is false and name is not an element of mappedNames, then
Add name as an element of the list mappedNames.
Let g be the result of calling the MakeArgGetter abstract operation with arguments name and env.
Let p be the result of calling the MakeArgSetter abstract operation with arguments name and env.
Call the [[DefineOwnProperty]] internal method of map passing ToString(indx), the Property Descriptor {[[Set]]: p, [[Get]]: g, [[Configurable]]: true}, and false as arguments.
Basically, the arguments
object gets a setter for each index so that assigning to arguments[i]
changes the value of the named parameter at position i
. There is language in the spec which makes it work vice-versa.
This should work in non-strict mode in any interpreter
(function (x) {
alert("x=" + x + ", arguments[0]=" + arguments[0]); // Both should be 0
arguments[0] = 1;
alert("x=" + x + ", arguments[0]=" + arguments[0]); // both should be 1
x = 2;
alert("x=" + x + ", arguments[0]=" + arguments[0]); // both should be 2
})(0);
But if you run the above on Firefox 5 with a use strict directive you get different behavior:
(function (x) {
"use strict";
alert("x=" + x + ", arguments[0]=" + arguments[0]); // Both should be 0
arguments[0] = 1;
alert("x=" + x + ", arguments[0]=" + arguments[0]); // x=0, arguments[0]=1
x = 2;
alert("x=" + x + ", arguments[0]=" + arguments[0]); // x=2, arguments[0]=1
})(0);
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