Splat operators in JavaScript, equivalent to *args and **kwargs in Python?

Question:

I use Python a lot, and I am just quickly learning JavaScript right now (or should I say re-learning). So, I wanted to ask, what is the equivalent of *args and **kwargs in JavaScript?

Asked By: Games Brainiac

||

Answers:

The nearest equivalent is the arguments pseudo-array.

Answered By: NPE

The closest idiom for *args would be

function func (a, b /*, *args*/) {
    var star_args = Array.prototype.slice.call (arguments, func.length);
    /* now star_args[0] is the first undeclared argument */
}

taking advantage of the fact that Function.length is the number of arguments given in the function definition.

You could package this up in a little helper routine like

function get_star_args (func, args) {
    return Array.prototype.slice.call (args, func.length);
}

and then do

function func (a, b /*, *args*/) {
    var star_args = get_star_args (func, arguments);
    /* now star_args[0] is the first undeclared argument */
}

If you’re in the mood for syntactic sugar, write a function which transforms one function into another one which is called with required and optional arguments, and passes the required arguments along, with any additional optional arguments as an array in final position:

function argsify(fn){
    return function(){
        var args_in   = Array.prototype.slice.call (arguments); //args called with
        var required  = args_in.slice (0,fn.length-1);     //take first n   
        var optional  = args_in.slice (fn.length-1);       //take remaining optional
        var args_out  = required;                          //args to call with
        args_out.push (optional);                          //with optionals as array
        return fn.apply (0, args_out);
    };
}

Use this as follows:

// original function
function myfunc (a, b, star_args) {
     console.log (a, b, star_args[0]); // will display 1, 2, 3
}

// argsify it
var argsified_myfunc = argsify (myfunc);

// call argsified function
argsified_myfunc (1, 2, 3);

Then again, you could just skip all this mumbo jumbo if you are willing to ask the caller to pass the optional arguments as an array to start with:

myfunc (1, 2, [3]);

There is really no analogous solution for **kwargs, since JS has no keyword arguments. Instead, just ask the caller to pass the optional arguments in as an object:

function myfunc (a, b, starstar_kwargs) {
    console.log (a, b, starstar_kwargs.x);
}

myfunc (1, 2, {x:3});

ES6 Update

For completeness, let me add that ES6 solves this problem with the rest parameter feature. See Javascript – '…' meaning

Answered By: user663031

I found a good solution here:
http://readystate4.com/2008/08/17/javascript-argument-unpacking-converting-an-array-into-a-list-of-arguments/

Basically, use function.apply(obj, [args]) instead of function.call. apply takes an array as the 2nd arg and ‘splats’ it for you.

Answered By: Luke W

ECMAScript 6 will have rest parameters which do the same thing as the splat operator.

Answered By: Cameron Martin

ES6 added a spread operator to JavaScript.

function choose(choice, ...availableChoices) {
    return availableChoices[choice];
}

choose(2, "one", "two", "three", "four");
// returns "three"
Answered By: Helio Santos

For those who might be slightly lost about *args and **kwargs magic variables read http://book.pythontips.com/en/latest/args_and_kwargs.html

Summary:
*args and **kwargs are just conventional ways of writing the magic variables. You could just say * and ** or *var and **vars. That said lets talk about the JavaScript equivalent in 2019.

*args in python represents a JavaScript Array e.g. ["one", "two", "three"] to pass that into a python function you would just define the function as def function_name(*args): meaning this function accepts "arrays" or "list if you wish" to call that you would simply use function function_name(["one", "two", "three"]):

same thing in JavaScript can be done by using :

function func(x,y,z){
  ...
}
let args = ["one", "two", "three"];

func(...args)

**or more dynamically as**

 function func(inputs){

   for(index of inputs){

      console.log(inputs[index]);
   }
}
let args = ["one", "two", "three"];

func(args)

Have a look at https://codeburst.io/a-simple-guide-to-destructuring-and-es6-spread-operator-e02212af5831

**kwargs on the other hand represent just an array of key value pairs(objects) that’s it. Thus
**kwargs e.g is [{"length": 1, "height": 2}, {"length":3, "height": 4}]

in python to define a function accepting array of objects you just say def function_name(**kwargs): then to call that you can do function_name( [{"length": 1, "height": 2}, {"length":3, "height": 4}]):

similarly in JS

const kwargs = [{"length": 1, "height": 2}, {"length":3, "height": 4}]

function func(obj1, obj2){
  ...
}

func(...kwargs);

**or more dynamically as:**

const kwargs = [{"length": 1, "height": 2}, {"length":3, "height": 4}]

function func(obj){
  for(const [key, value] in Object.entries(obj)){
    console.log(key, ": ", value)
 }

func(kwargs);
Answered By: N Djel Okoye

use array to pass arugment dynamic (ES6), in javascript I think this is the splat operators in javascript equivalent to args and kwargs in python

let argus = [1, 'Jone Doe'];
function message(userId, name){
  console.log(userId, name);
}
message(...argus );

Answered By: Mahmoud Magdy
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.