12

I wanted to have an optional boolean parameter to a function call:

function test() {
  if (typeof(arguments[0]) === 'boolean') {
    // do some stuff
  }
  // rest of function
}

I want the rest of the function to only see the arguments array without the optional boolean parameter. First thing I realized is the arguments array isn't an array! It seems to be a standard Object with properties of 0, 1, 2, etc. So I couldn't do:

function test() {
  if (typeof(arguments[0]) === 'boolean') {
    var optionalParameter = arguments.shift();

I get an error that shift() doesn't exist. So is there an easy way to remove an argument from the beginning of an arguments object?

1
  • Just a guess: delete arguments[0]? Commented Nov 11, 2013 at 10:19

3 Answers 3

29

arguments is not an array, it is an array like object. You can call the array function in arguments by accessing the Array.prototype and then invoke it by passing the argument as its execution context using .apply()

Try

var optionalParameter = Array.prototype.shift.apply(arguments);

Demo

function test() {
    var optionalParameter;
    if (typeof (arguments[0]) === 'boolean') {
        optionalParameter = Array.prototype.shift.apply(arguments);
    }
    console.log(optionalParameter, arguments)
}
test(1, 2, 3);
test(false, 1, 2, 3);

another version I've seen in some places is

var optionalParameter = [].shift.apply(arguments);

Demo

function test() {
    var optionalParameter;
    if (typeof (arguments[0]) === 'boolean') {
        optionalParameter = [].shift.apply(arguments);
    }
    console.log(optionalParameter, arguments)
}
test(1, 2, 3);
test(false, 1, 2, 3);

Sign up to request clarification or add additional context in comments.

5 Comments

Note that this will affect any named arguments as well, and has a particularly interesting effect on the last argument provided when it's accessed as a named argument. If you have function foo(a, b, c) and you call foo(1, 2, 3) and do the shift above, both b and c will end up being 3. This may be what you want. Or not.
Surprised this works! so shift not only returns back the first element, but converts the Object passed in to an array and then back into an Object with the first element removed? Exactly what I was looking for, but surprising...
@at that's not actually what it does. The "shift" code runs and "pretends" that the object is really an array; it performs no conversion. It's for that reason that this trick has the effect noded by Mr. Crowder. If you need to do this sort of thing, you should probably just convert arguments to an array and work from there.
If you want to leave arguments untouched and create a new array use slice: var newArguments = [].slice.call(arguments, 1);
What's important to understand is that in Javascript, functions are themselves objects and so can have a life on their own. You can take them from one object and put them onto another. Combine this with the fact that all array functions, by contract, only depend on the object having a length property and you can see why this solution works.
2

As Arun pointed out arguments is not an array

You will have to convert in into an array

var optionalParameter = [].shift.apply(arguments);

1 Comment

Arun's original answer did not have the alternative solution. It was added later
1

It's not fancy but the best solution to remove the first argument without side effect (without ending with an additional argument as would do shift) would probably be

  for (var i=0;i<arguments.length;i++) arguments[i]=arguments[i+1];

Example :

function f(a, b, c, d) {
  for (var i=0;i<arguments.length;i++) arguments[i]=arguments[i+1];
  console.log(a,b,c,d); 
}
f(1,2,3,4); // logs 2,3,4,undefined

1 Comment

After your code runs, arguments.length === 4. I think you should finish the job by setting it to arguments.length-1 after the for loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.