Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this legal javascript? Passing arguments to function and having it change them

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.

like image 772
Ariel Avatar asked Jun 22 '11 00:06

Ariel


People also ask

Can you pass a function as an argument in JavaScript?

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.

Can a function change the value of its arguments?

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.

Can we pass a variable number of arguments to a function JavaScript?

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.

What is passing an argument JavaScript?

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.


1 Answers

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

  1. Add name as an element of the list mappedNames.

  2. Let g be the result of calling the MakeArgGetter abstract operation with arguments name and env.

  3. Let p be the result of calling the MakeArgSetter abstract operation with arguments name and env.

  4. 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);
like image 120
Mike Samuel Avatar answered Sep 28 '22 07:09

Mike Samuel