stevemao
stevemao

Reputation: 1483

What's the difference between ...args and arguments in a function

What's the difference between

function(...args) {
  // args is an array
}

and

function() {
  // arguments is an array-like
}

Since it's pretty easy to convert an array-like to array, is there any other differences?

A similar question:

myFunction.apply(null, args);

and

myFunction(...args);

Upvotes: 1

Views: 1141

Answers (3)

PowerKiKi
PowerKiKi

Reputation: 4738

From MDN, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters#the_difference_between_rest_parameters_and_the_arguments_object :

There are four main differences between rest parameters and the arguments object:

  • The arguments object is not a real array, while rest parameters are Array instances, meaning methods like sort(), map(), forEach() or pop() can be applied on it directly.
  • The arguments object has the additional (deprecated) callee property.
  • In a non-strict function with simple parameters, the arguments object syncs its indices with the values of parameters. The rest parameter array never updates its value when the named parameters are re-assigned.
  • The rest parameter bundles all the extra parameters into a single array, but does not contain any named argument defined before the ...restParam. The arguments object contains all of the parameters — including the parameters in the ...restParam array — bundled into one array-like object.

Upvotes: 0

JMM
JMM

Reputation: 26797

Re: differences between apply() and spread (when passing null or such as the thisArg to apply() as in the example):

myFunction.apply(null, args);
myFunction(...args);

Aside from spread being newish, so not as widely supported currently, apply() accepts an array or array-like object of arguments, whereas spread will work on any iterable. For example, you could spread a Set or Map as the arguments while you couldn't pass it as the argArray argument to apply() (though you could of course spread it as the arguments to call(): myFunction.call(whatever, ...someIterable)).

Since it's pretty easy to convert an array-like to array, is there any other differences?

It's not really that easy for arguments. Doing it wrong (or perhaps at all) can cause the JS engine to deoptimize the function, and if there is a right way to do it that avoids that it requires annoying boilerplate to do it.

Upvotes: 2

Amadan
Amadan

Reputation: 198324

  1. ...args is new; was not available till ES6
  2. You can use it for part of the argument structure: function(foo, bar, ...others)
  3. You get an array, so no more Array.prototype.slice.call(arguments, 0)
  4. ...args is more obvious to code readers
  5. Now that we have matches and lighters, we don't need to rub sticks to make fire

However, as a corollary to 1, not everything supports it yet.

Upvotes: 6

Related Questions