Variadic functions referred to as "variable-arity" functions, can accept an arbitrary number of arguments when called - it provides flexibility and convenience, particularly when working with functions that require varying numbers of inputs. JavaScript supports variadic functions through the 'rest' operator, making it easy to define and use them in your code.

## Benefits

1. Flexibility: Variadic functions provide the ability to work with a varying number of arguments, making them perfect for handling different input sizes.
2. Code Reusability: By allowing an arbitrary number of arguments, developers can reuse a single function for various purposes, reducing code duplication.

## rest operator

Variadic functions can be easily implemented using the 'rest' syntax. The rest syntax is denoted by three dots (…) before the function parameter name:

``````function sum(...numbers) {
return numbers.reduce((total, current) => total + current, 0);
}
function multiply(...numbers) {
return numbers.reduce((total, current) => total * current, 1);
}

console.log(sum(1, 2, 3, 4, 5, 6));       // prints: 21
console.log(multiply(1, 2, 3, 4, 5, 6));  // prints: 720``````

## Using with other parameters

Variadic functions can also be combined with other parameters.

### Variable Number of Parameters

Here is an example of displaying a greeting for an variable number names:

``````function greet(greeting, ...names) {
names.forEach(name => console.log(`\${greeting}, \${name}!`));
}

greet('Good morning', 'Alice', 'Bob', 'Charlie');
// prints:
//   Good morning, Alice!
//   Good morning, Bob!
//   Good morning, Charlie!``````

### Merging arrays

We can use the spread syntax to merge all the arrays into a single array:

``````function mergeArrays(arr1, arr2, ...rest) {
return [...arr1, ...arr2, ...rest];
}

const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const array3 = [7, 8, 9];

const mergedArray = mergeArrays(array1, array2, ...array3);
console.log(mergedArray);  // prints: [1, 2, 3, 4, 5, 6, 7, 8, 9]``````

A slightly simpler version of mergeArrays:

``````function mergeArrays(...arrays) {
return [].concat(...arrays);
}

const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const array3 = [7, 8, 9];

const mergedArray = mergeArrays(array1, array2, array3);
console.log(mergedArray);  // prints: [1, 2, 3, 4, 5, 6, 7, 8, 9]``````

### Sorting by multiple properties

the `sortByProperties` function takes a property name as its first parameter, followed by a variadic parameter `rest` that contains additional property names. The function returns a comparator function that sorts

``````function sortByProperties(property, ...rest) {
return function (a, b) {
if (a[property] < b[property]) {
return -1;
} else if (a[property] > b[property]) {
return 1;
} else {
if (rest.length === 0) {
return 0;
} else {
const [nextProperty, ...remainingProperties] = rest;
return sortByProperties(nextProperty, ...remainingProperties)(a, b);
}
}
};
}

const people = [
{ name: 'Alice', age: 30, city: 'New York' },
{ name: 'Bob', age: 30, city: 'San Francisco' },
{ name: 'Charlie', age: 25, city: 'London' },
];

const sortedPeople = people.sort(sortByProperties('age', 'city', 'name'));
console.log(sortedPeople);
// prints
// [
//   { name: 'Charlie', age: 25, city: 'London' },
//   { name: 'Alice', age: 30, city: 'New York' },
//   { name: 'Bob', age: 30, city: 'San Francisco' }
// ]``````

### Dynamic object property assignment

The rest operator can be utilized to dynamically assign properties to an object:

``````function createPerson(name, age, ...extra) {
const person = {
name,
age,
};

for (const prop in extra) {
person[prop] = extra[prop];
}

return person;
}

const person = createPerson("Charlie", 30,
{ city: "London", country: "UK" });
console.log(person);
// prints { '0': { city: 'London', country: 'UK' }, name: 'Charlie', age: 30 }
``````