24

I have a function that can accept any number of arguments...

const getSearchFields = () => {        
    const joined = arguments.join('/'); 
};

I want a string of all the arguments being passed to the function joined with the / character. I keep getting this error:

args.join is not a function

Can someone please tell me what I'm doing wrong?

alex
  • 479,566
  • 201
  • 878
  • 984
  • Why edit it to use ES6 syntax? – Tim Down Apr 25 '18 at 09:09
  • @TimDown Felt right when I was updating it. I guess there's valid arguments against doing it, if that''s what you're hinting at. – alex Apr 25 '18 at 23:20
  • I dunno really, just seems a bit odd when the answers from 2009 are in ES3. I'm not on here enough now to know whether it's considered good or bad to revise old questions to modern syntax. – Tim Down Apr 26 '18 at 11:29
  • @TimDown AFAIK, it's encouraged to keep answers always up-to-date, even if the question goes stale. In this case, now the question looks less dated. – alex Apr 26 '18 at 13:53
  • 1
    @alex, I have also updated [my answer](https://stackoverflow.com/a/1424728/5445) to provide an ES6 way to do it. Thanks. – Christian C. Salvadó Oct 06 '18 at 16:16
  • @CMS Wow, you're back :) – alex Oct 08 '18 at 08:54

8 Answers8

48

arguments is a pseudo-array, not a real one. The join method is available for arrays.

You'll need to cheat:

var convertedArray = [];

for(var i = 0; i < arguments.length; ++i)
{
 convertedArray.push(arguments[i]);
}

var argsString = convertedArray.join('/');

Similar to other posts, you can do the following as shorthand:

var argsString = Array.prototype.join.call(arguments, "/");
David Andres
  • 31,351
  • 7
  • 46
  • 36
14

As all said above, the arguments object is not really an array, but you can apply array functions directly, by accessing the Array.prototype and executing them with apply or call to change the context:

var argsString = Array.prototype.join.call(arguments, '/');

Edit: Since the original question asked almost 9 years ago was updated to use ES6 syntax, I feel the need to provide an ES6 answer now the language provides native constructs to handle this kind of situations.

The ES6 standard introduces the spread operator, which you can easily use to receive the arguments as an array object, for example:

function sum(...numbers) {
  return numbers.reduce((sum, value) => sum + value);
}

console.log(sum(1,2,3,4)); // 10

Applied to your example:

const getSearchFields = (...fields) => {        
  const joined = fields.join('/'); 
};

You can also use the spread operator to do function calls, let's say you have an array, and you want to call a function, passing each element of the array as an argument of the function call, now you can simply:

function sum(a, b, c, d) {
  return a + b + c + d;
}

var array = [1, 2, 3, 4];
console.log(sum(...array)); // 10

Also you can expect some arguments and have the rest of the arguments passed as the last parameter defined:

function processList(first, ...rest) {
  // ...
}

And there are more uses of the spread operator that go beyond the scope of this question, for example object copying, spreading arrays in arrays, etc...

Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
8

If you are using jQuery 1.2+, you can use $.makeArray():

Convert an array-like object into a true JavaScript array.

From the example in the question, just use this line

var args = $.makeArray(arguments);
user193130
  • 8,009
  • 4
  • 36
  • 64
5

arguments is not really an array.

try this:

var args = [].splice.call(arguments,0);
var argsString = args.join('/');
Russ Bradberry
  • 10,705
  • 17
  • 69
  • 85
2

The problem is that arguments is an array-like object (it has numbered properties mapping to the passed arguments and a length property), but it actually isn't an array.

In the old days, you could make it into a real array with Array.prototype.slice.call(arguments) (among other methods).

However, we're a bit luckier these days (depending on your supported platforms of course). You can either do...

const getSearchFields = (...args) => {
   Array.isArray(args); // true
};

...or...

const getSearchFields = () => {
   const args = Array.from(arguments);
   Array.isArray(args); // true
};

The first example is preferred because...

  • you get the normal array creation without an extra step in the function body
  • arguments is a magic variable (it's not defined explicitly, so where did it come from?)
  • it has funny behaviour with named args in non-strict mode (note that you should always 'use strict')
  • the first example has much clearer intent (the creation of an array of all arguments is explicit).
alex
  • 479,566
  • 201
  • 878
  • 984
0

arguments is not a JavaScript array; it's a special object that doesn't have a join method.

Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194
-1

If your are getting while posting http request in angular4 user HttpHeaders. Please check below answer. After usring HttpHeaders my issue is resolved.

this.headers  = new HttpHeaders({ 'Authorization': token1, 'X-IBM-Client-Id': 'ddddddd' });

values.join is not a function in the file http.es5.js Angular 4

user3198259
  • 178
  • 3
  • 13
-2

You have to make assignment to a variable for it to work.

var a = ['Wind', 'Rain', 'Fire'];

var myVar1 = a.join();

var myVar2 = a.join(', ');

var myVar3 = a.join(' + ');

var myVar4 = a.join('');
alex
  • 479,566
  • 201
  • 878
  • 984