0

Given this function:

function foo( a,b,c ) {
    //
}

How can you do something, say use console.log() for each argument? I know you can see the arguments by using the arguments keyword. Arguments seems to return what looks like an Array (but is of type "object" [suprise.. not]) but it doesn't support .forEach, I am using Chrome.

I tried modifying the function to this, and expected it to work:

function foo( a,b,c ) {
    arguments.forEach(function( arg ){
        console.log( arg );
    });
}

You get the error that TypeError: Object # has no method 'forEach'.

7 Answers 7

5

The arguments object doesn't have a forEach method, so you need to iterate over it either with a for loop, or a for...in loop.

​function foo () {
    for (var i = 0; i < arguments.length; i++) {
        console.log(arguments[i]);    
    }
}

foo("Foo", { "bar": 0 }); // Output: Foo, Object {bar: 0} 

Or

​function foo () {
    for (var arg in arguments) {
        console.log(arguments[arg]); 
    }    
}

foo("Foo", "Bar"); // Output: Foo, Bar
Sign up to request clarification or add additional context in comments.

7 Comments

Won't using for..in on arguments also iterate over the length, callee and other properties?
@RocketHazmat No. The length property isn't enumerable. The descriptor for length in the example above is {value: 2, writable: true, enumerable: false, configurable: true}.
In your second example why is arguments[arg] required? Why can't you just console.log(arg)? I see, I had a typo before, the arg keyword is an index.
@CaleyWoods Because 'arg' represents a key, and not a value. So we have to pass that key once again to the arguments object in order to get the corresponding value.
Jonathan Sampson - I've accepted your answer as I feel it answers the exact question I asked. It didn't address my next question (which is no fault of yours) but some of the other answers did illustrate using Array.protoype.forEach.call() which answered my next question of "How do you make arguments respond to forEach?". I believe your for...in solution is even more readable than calling .forEach.
|
3

Or you can use a hack:

Array.prototype.forEach.call(arguments, function (arg) {
    console.log(arg);
});

arguments isn't an array, but it's close enough that you can apply Array's prototype and use the regular array functions. We're just grabbing Array's implementation and applying it forcefully to arguments.

3 Comments

This is again what I was headed towards. I commented an explanation on phant0ms answer.
You could further simplify this to Array.prototype.forEach.call(arguments, console.log, console) if you only want to log it, but I doubt that's what you're after.
tjameson that is correct. I have another function I'm looking to call and just wanted a clean way to do that and avoid: someFn(a); someFn(b);
2

From MDN:

// convert to array
var args = Array.prototype.slice.call(arguments);
args.forEach...

2 Comments

This is along the lines of what I was looking for. The answers about using a regular for loop were good answers but it let me to the question, "If arguments doesn't respond to forEach, how can I make it do that?". This answer answers the question I hadn't asked yet. With that said, is this something that needs to be done within each function or can I permanently convert the arguments object into an array (not saying I'd want to, just curious.) ?
@CaleyWoods No, you can't do it permanently, you'll have to do it for each function.
1

Do a loop on arguments.length. arguments isnt an Array so it doesn't have the forEach prototypal method.

for ( var i = 0, l = arguments.length; i<l; ++i ) {
  doSomething( arguments[i] );
}

Comments

1

Just use a normal for loop.

function foo( a,b,c ) {
    for(var i = 0, len = arguments.length; i < len; i++){
        console.log(arguments[i]);
    }
}

Or you can convert it to a real array.

function foo( a,b,c ) {
    var args = Array.prototype.slice.call(arguments);
    args.forEach(function( arg ){
        console.log( arg );
    });
}

Comments

0
var show_args = function (){

    for(var ar in arguments){
        console.log(arguments[ar])
    }
}

Comments

0

You can convert the "arguments" into an array by calling the array slice method on it:

function foo(a, b, c) {
  var argArray = Array.prototype.slice.call(arguments);
  argArray.forEach(function(x) {
    // ...
  });
}

3 Comments

Submitted the the same solution the very same second... Impossible! This must be one of those strange quantum world things.
@phant0m, low-hanging fruits exist in the normal world too. :)
@bzlm I'm more surprised by the timing than the contents ;)

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.