9

Recently I started learning JavaScript through Nicholas C. Zakas' book Professional JavaScript For Web Developers and I came across some questions that I could not solve by myself.

As the title says, that's all about named arguments and arguments object in JavaScript functions.

E.g. we have this piece of code:

function doAdd(num1 , num2) {
     arguments[1] = 10;
     alert(arguments[0] + num2);
}

doAdd(10 , 20);

The book says that values in the arguments object are automatically reflected by the corresponding named arguments, so num2 enters the function with a value of 20 and then it gets overwritten via arguments[1] and finally gets a value of 10.All good all clear up to this point. Then it says that

this effect goes only one way: changing the named argument does not result in a change to the corresponding value in arguments.

And that's where the problems start.

I tried to modify this code a bit to understand what the author says but I failed.

E.g.

function doAdd(num1 , num2) {
     arguments[1] = 10;
     num2 = 40;
     alert(arguments[0] + arguments[1]);
}

doAdd(10 , 20);

This time num2 enters function with a value of 20 again, it changes to 10 via arguments[1] and then it changes once more to 40 via the named argument num2 this time. Alert pops up 50, since a change to a named argument does not result in a change to the corresponding value in arguments. Why does alert not pop up 20?

2
  • 2
    Mr. Zakas' book is in error.
    – Pointy
    Commented May 18, 2014 at 13:23
  • I am reading the book and I got the same question... thank you!
    – George
    Commented May 20, 2014 at 1:04

2 Answers 2

6

This is because the book assumes you're using strict mode.

If you run the code in strict mode, you'll get the behavior you'd expect given what's written in the book.

function doAdd(num1 , num2) {
     "use strict";
     arguments[1] = 10;
     num2 = 40;
     alert(arguments[0] + arguments[1]);
}
doAdd(10 , 20); // this alerts 20, alerts 50 in nonstrict mode

A little known fact is that the entire point of strict mode is to avoid this sort of dynamic scoping (which is why arguments is fixated, with isn't allowed and eval behaves differently). Aside from clarity gains, this allows for massive speed improvements.

Also see this:

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.

This is what NCZ means in context, quoting the book itself:

Strict mode makes several changes to how the arguments object can be used. First, assignment, as in the previous example, no longer works. The value of num2 remains undefined even though arguments[1] has been assigned to 10. Second, trying to overwrite the value of arguments is a syntax error. (The code will not execute.) - Page 82, Language Basics, Professional JavaScript, Nicholas C. Zakas

10
  • It was an answer attempt , i'm sry i just fixed it. Commented May 18, 2014 at 14:49
  • @user3649693 Please leave your uncertainties as a comment then, so I can respond to it - for future visitors. Commented May 18, 2014 at 15:02
  • But aren't we over writting the value of arguments[1] (which is 10) with the value of num2 (which is 40) ? Book assumes we are stict mode but there is no syntax error and script runs smooth.This kinda confuses me. Commented May 18, 2014 at 15:11
  • @user3649693 reassigning arguments means arguments = [] or something like that. Assigning to a property of arguments means code that looks like arguments[1] = 10 , while this is allowed, it changes a copy of the argument, and not the argument itself. Commented May 18, 2014 at 15:14
  • This is a bit less confusing right now. How could we alter that piece of code above so it would throw a syntax error in strict mode? Commented May 18, 2014 at 15:22
1

Quoting from ECMA 5.1 Specifications for Arguments Object,

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.

It didn't alert 20 because, as per the ECMA 5.1 specifications, in a non-strict mode function, mutating arguments object with the numeric key, will also change actual formal parameter corresponding to the numeric key.

In your case, when you change arguments[1], you are also changing the second parameter. The same way, when you change num2, you are also changing arguments[1].

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.