8

Consider this JavaScript function:

var f = function (a) {
  console.log(a+" "+arguments[0]);
  a = 3;
  console.log(a+" "+arguments[0]);
}

I would expect that a and arguments[0] reference the same value only up to the second statement of the function. Instead they appear to always refer the same value: f(2) causes

2 2
3 3

and f({foo: 'bar'}) causes:

[object Object] [object Object]
3 3

Are argument identifiers and the arguments identifier linked in a special way?

Eric
  • 321
  • 3
  • 9
  • 1
    Yes, and it's a bad thing and I think that is going to change anyway. – Felix Kling Mar 02 '15 at 16:44
  • This is a duplicate I think, I'm sure this is referenced somewhere..I'll try and dig it out – Liam Mar 02 '15 at 16:46
  • possible duplicate of [Is JavaScript a pass-by-reference or pass-by-value language?](http://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language) – Liam Mar 02 '15 at 16:48
  • @Liam: How is that a duplicate of this question? – Felix Kling Mar 02 '15 at 16:48
  • `I would expect that a and arguments[0] reference the same value only up to the second statement of the function. Instead they appear to always refer the same value`, i.e. they are reference types...Also your answer basically says, this is a reference type. – Liam Mar 02 '15 at 16:51
  • @Liam: Well, the linked question talks more about how values/variables are treated in general, doesn't it? `arguments` is a special case. JavaScript is still pass-by-value. It's impossible to recreate the behavior of `arguments` in user-land code. – Felix Kling Mar 02 '15 at 16:52
  • Well, no, because they behave in the same manner, i.e. there are referencing the same memory. It's the same thing. `This means that changing the property changes the corresponding value of the argument binding and vice-versa.` – Liam Mar 02 '15 at 16:55
  • 1
    @Liam: I'm not denying that. I'm just saying that the linked question covers a different topic. The linked question is about how values are passed *to* functions. This question is about how `arguments` behaves. Slightly related, but yet different. – Felix Kling Mar 02 '15 at 16:59

1 Answers1

7

Are argument identifiers and the arguments identifier linked in a special way?

Yes (but only in non-strict mode).

From the specification (ES6, ES5):

For non-strict mode functions the integer indexed 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.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143