11

So this code works perfectly

var arr = [1, 2, 3, 4];
arr.forEach(function (el) {
    console.log(el);
})

But if i try to do this:

function printArgsInfo() {
    arguments.forEach(function (el) {
        console.log(el);
    });
}
printArgsInfo(2, 3, 2.5, -110.5564, false);

arguments.forEach is not a function

Even though arguments is an array and if Itry to do this with a for in loop it still works.

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Все Едно
  • 746
  • 3
  • 10
  • 24

3 Answers3

18

arguments is an array-like object, but not an array:

var doThing = function() {
    console.log(arguments.constructor.name)
    console.log([].constructor.name)
}

doThing("someArgument")


Will return Object for arguments and Array for the empty array [].

ES6 and newer

With ES6, you could use rest parameters ..., as torazaburo suggests.

The rest parameter syntax allows us to represent an indefinite number of arguments as an array.

function printArgsInfo(...args) {
    args.forEach(el => console.log(el));
}

printArgsInfo(2, 3, 2.5, -110.5564, false);

ES5 and older

For ES5 and older, you could borrow the method from Array#forEach and call it with argument as thisArg.

function printArgsInfo() {
    [].forEach.call(arguments, function (el) {
        console.log(el);
    });
}

printArgsInfo(2, 3, 2.5, -110.5564, false);
mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • 3
    I'm surprised you don't suggest the obvious `[...arguments].forEach`. Or more preferably, just say `function printArgsInfo(...args)`. –  Jun 08 '17 at 12:15
  • 1
    @torazaburo, right, added that as well, thank you for the hint. – Nina Scholz Jun 08 '17 at 12:49
7

Per the MDN Docs:

The arguments object is an Array-like object corresponding to the arguments passed to a function.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments

So, it is not a true array and does not share the Array object's prototype -- which is where the forEach method is defined.

Interestingly, also from the MDN docs:

You can also use the Array.from() method or the spread operator to convert arguments to a real Array

var args = Array.from(arguments);

So, here is a working example with your code:

function printArgsInfo() {
    var args = Array.from(arguments);

    args.forEach(function (el) {
        console.log(el);
    });
}

printArgsInfo(2, 3, 2.5, -110.5564, false);
Levi Mootz
  • 306
  • 1
  • 4
4

Even though arguments is an array

It isn't.

function myFunc() {
    console.log(arguments instanceof Array);
}

myFunc(1,2,3);

The Arguments object is an array-like object. It isn't an array.

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Also maybe see https://stackoverflow.com/questions/960866/how-can-i-convert-the-arguments-object-to-an-array-in-javascript – Chris Lear Jun 08 '17 at 11:40
  • console.log(typeof arguments); yes low it says its an object and it seems logical not to be albe to foreach it, never tought that it wasn't an array – Все Едно Jun 08 '17 at 11:40
  • `console.log(typeof [])` — arrays are objects (but not all objects are arrays). – Quentin Jun 08 '17 at 11:43