I'm a Javascript novice so please excuse the fundamental question.
I'm working my way through 'Professional Javascript For Web Developers' and in Chapter 3, "Understanding Arguments" section, it discusses accessing function arguments with the arguments[] keyword.
One of the examples shows that you can modify the values in arguments[]:
function twoNums(num1, num2) {
arguments[1] = 10;
console.log(arguments[0] + num2);
}
twoNums(4,8); output = 14
But it goes on to say that "This effect goes only one way: changing the named argument does not result in a change to the corresponding value in arguments."
However, changing the code to:
function twoNums(num1, num2) {
num2 = 10;
console.log(arguments[0] + arguments[1]);
}
twoNums(4,8); output = 14
results in the same output so the value in 'arguments[1]' is definitely changing.
Is this:
Thanks,
Neil
ANSWERED: A combination of answers solved my problem. Thanks everyone.
It is supposed to work that way, unless in strict mode:
function foo(a) {
"use strict";
console.log(a, arguments[0]);
a = 10;
console.log(a, arguments[0]);
arguments[0] = 20;
console.log(a, arguments[0]);
}
foo(1);
// output:
// 1 1
// 10 1
// 10 20
The ES5 specification addresses that on section 10.6:
NOTE 1 For non-strict mode functions the array index (defined in 15.4) named 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.
Maybe it worked differently on ES3 (the previous version), but I doubt it (since they had to add a special case for strict mode).
Interesting fact: the presence of an eval call in the function can influence how the arguments object behave in some browsers, which is extremely weird. The use of the non-standard functionName.arguments reference also has an impact. See Why does an unexecuted eval have an effect on behavior in some browsers?, and my answer to it.
There is an error in the book, by the looks of things: if you reassign any of the arguments passed, the arguments object will change (both reference the same value).
Perhaps, though, what was meant in the book was this:
function f(n1, n2)
{
arguments[0] = 2;
console.log(arguments[0] + arguments[1]);
}
f(1, 2);//logs 4
f(1234,2);//logs 4
But, honestly, it shouldn't really matter. The arguments object should be treated as a read-only object. It's a good idea to uphold the mantra "Don't change objects you don't own" in JS. It's a bad idea trying to change the Object.prototype, as it is not the best of ideas to change the behaviour of any object (console, window...) by deleting and adding methods at random.
If you want to get some more details on arguments, or anything else MDN is there to help. I've not looked at all code examples there, but AFAIKT there's no code that effectively changes the arguments object.
Some time ago I think I read an article my Douglas Crockford on the matter, where he gave an example of how changing the arguments object actually lead to unexpected behaviour (arguments swapping places and all that).
Edit:
I'd thought I'd not go into strict mode, but as bfavaretto's answer pointed out: strict-mode actually does make the arguments object a read-only object. That's terrific news, and now I have all the more reason to love the way JS is going. ES6 will introduce block scoping and probably make the arguments object read-only all the time (at least, I hope it will).
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