Reputation: 63
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.
Upvotes: 3
Views: 2130
Reputation: 76395
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).
Upvotes: 2
Reputation: 71918
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.
Upvotes: 2
Reputation: 10719
it will work that way only in strict mode..
"use strict"
The Arguments object has one very unusual feature. In non-strict mode, when a function has named parameters, the array elements of the Arguments object are aliases for the parameters that hold the function arguments. The numbered elements of the Arguments object and the parameter names are like two different names for the same variable. Changing the value of an argument with an argument name changes the value that is retrieved through the arguments[] array. Conversely, changing the value of an argument through the arguments[] array changes the value that is retrieved by the argument name. Here is an example that clarifies this:
function f(x) { console.log(x); // Displays the initial value of the argument arguments[0] = null; // Changing the array element also changes x! console.log(x); // Now displays "null" } This is emphatically not the behavior you would see if the Arguments object were an ordinary array. In that case, arguments[0] and x could refer initially to the same value, but a change to one would have no effect on the other.
This special behavior of the Arguments object has been removed in the strict mode of ECMAScript 5. There are other strict-mode differences as well. In non-strict functions, arguments is just an identifier. In strict mode, it is effectively a reserved word. Strict-mode functions cannot use arguments as a parameter name or as a local variable name, and they cannot assign values to arguments.
Here is a great (and recent) article on this topic: https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-8/function-arguments-and
I Suggest you use it :)
Upvotes: 1