JavaScript Parameters and Arguments

Uriel Rodriguez
The Startup
Published in
6 min readJan 26, 2021

--

In programming, functions are foundational. They modularized logic which creates reusability and cleaner code. Sometimes, functions are able to carry out their logic with outside input known as arguments. Arguments are then used within a function’s body to compute a return value. Functions are able to utilize arguments through function defined local variables called parameters. JavaScript functions also allow many ways to work with parameters and arguments, some of which are not too familiar.

When working with parameters and arguments, the simplest variation is a function that expects a single argument.

function greet(greeting) {
console.log(greeting);
}
greet("hello"); // => hello

However, because JavaScript functions do not check for argument types, or if an argument was passed to a function that expected one, unexpected results can happen.

greet(); // => undefined
greet(3); // => 3

To prevent these sort of situations from happening, we can define what are known as parameter default values. The default values allow to provide an adequate argument to the function invocation in the event that a function is invoked without a necessary argument.

function greet(greeting = "hello") {
console.log(greeting);
}
greet(); // => hello
greet("good morning"); // => good morning

In the event of passing an argument of a data type not intended for the parameter, we can manually check for the type and produce an error message if the wrong data type is passed.

function greet(greeting = "hello") {
if (typeof greeting !== "string") {
throw new Error("greet() argument is not a string");
}
console.log(greeting);
}
greet(3); // => Error: greet() argument is not a string
greet("hi"); // => hi

This example shows how type checking can be accomplished with JavaScript but it is more commonly handled with a language extension called TypeScript which adds type checking functionality to JavaScript.

JavaScript functions also allows for parameter default values to be computed by variables, function invocations and even other parameters. So for example:

const myObj = {};
function greet(greeting = "sup") {
if (typeof greeting !== "string") {
throw new Error("greet() argument is not a string");
}
console.log(greeting);
return greeting;
}
function newPerson(obj = myObj, greeting = greet()) {
obj.greeting = () => console.log(greeting);
return obj;
}
// provide no arguments
const firstPerson = newPerson();
console.log(firstPerson); // => { greeting: [Function (anonymous)] }
firstPerson.greeting(); // => sup

The example show that the newPerson() function sets the “myObj” variable’s value as the default value for the parameter “obj” and sets the default parameter value of the “greeting” argument to the return value of greet(). In addition, parameters can be used to set other parameters such as in the following example.

const rectangle = (width, height = width * 2) => ({ width, height });

The function expression mandatorily receives one argument, “width” which is then optionally used to calculate the “height” property on the returned rectangle object. If a “height” argument is provided, then that argument is used instead.

Another feature of parameters and arguments in JavaScript can be seen when a function is passed more arguments than defined parameters. In that case, the excess arguments are simply ignored, as long as the defined parameters were provided with values or arguments.

function eat(food) {
console.log("eating " + food);
}
eat("eggs", "toast"); // => eating eggs

Actually, the remaining arguments are not simply ignored although it seems that way. Within every function declaration body, there is another hidden value, aside from the others which were mention in my previous blog “Understanding the Invocation Context in JavaScript” , that is the “arguments” array-like object. The “arguments” object is an iterable object that contains every argument passed to the function. It stores the arguments using numerical, array-like index and can be iterated over using array iterators like the for-of loop.

function eat(food) {
console.log("eating " + food);
console.log(arguments);
}
eat("eggs", "toast");
// => eating eggs
// => { '0': 'eggs', '1': 'toast' }

The “arguments” keyword is reserved and cannot be used as a parameter name or within the function body as a local variable. This feature was designed to allow an arbitrary amount of arguments when invoking a function without having to specify an arbitrary amount of parameters in the function definition. It is also an outdated way to utilize multiple arguments and is less efficient than the modern rest parameters method.

function eat(...food) {
for (let item in food) {
console.log("eating " + item);
}
// log the rest parameter
console.log(food);
}
eat("eggs", "toast", "bacon");
// => eating eggs
// => eating toast
// => eating bacon
// => [ 'eggs', 'toast', 'bacon' ]

In the example above, the “…” special syntax in the “food” parameter definition is used to indicate that an arbitrary amount of arguments will be accepted when invoking the function. It also aggregates all the arguments passed to the function within an actual array, unlike the array-like object with “arguments”. It is useful to note that when using the “…” notation within a function definition, it establishes the rest parameters array within the function body and which will default to an empty array in case no arguments are provided. Because of this, the rest parameter does not require a default value, it will default to the empty array.

A common way to utilize the rest parameter is with the spread operator which is a point of confusion because it share the same “…” special syntax. For example:

function max(...numbers) {
// provide a starting point
let maxVal = -Infinity;
for (let num of numbers) {
typeof num === "number" ? continue : throw new Error("max() arguments must be numbers");
maxVal = num > maxVal ? num : maxVal;
}
return maxVal;
}
const nums = [1, 2, 3];
max(...nums); // => 3

In this example, the function is defined with a rest parameter, accepting an arbitrary amount of integer arguments. The function also ensures that integers are provided as arguments to produce an appropriate return value for the “maxVal”. When the max() function is invoked, the argument provided is spread, in this case the array “nums” has its elements spread as arguments and gathered by the rest parameter “…numbers”.

In addition to spreading out arguments or gathering them into a single array, arguments can be destructured or have their properties extracted into variables which can then be used within the function.

function multiply({ num1, num2 }) {
console.log(num1 * num2);
}
const numbers = { num1: 3, num2: 5 };
multiply(numbers); // => 15

This example is shows a function definition with a destructuring syntax to define the parameters of the function. The function expects an object as an argument containing a “num1” and “num2” property within it. It then logs the product of the two properties. Also, the two properties expected are expressed in the destructuring syntax using variables of the same name as the properties of the expected argument object. Other variables can be used to represent the expected properties by using another syntax. But finally, the multiply() function is then invoked with the “numbers” object containing the two expected properties.

// rename expected properties for function body implementation
function multiply({ num1: x, num2: y }) {
console.log(x * y);
}
const numbers = { num1: 3, num2: 5 };
multiply(numbers); // => 15

// destructuring works with arrays as well
function divide([ ele1, ele2 ]) {
console.log(ele2 / ele1);
}
const nums = [3, 15];
divide(nums); // => 5

Unlike destructuring objects which expect exact property names, destructuring arrays do not require exact names so elements can be represented with any variable name.

With that, you can see how dynamic functions can be and we have only focused on their parameters and arguments. These techniques can assist in writing more efficient and cleaner functions. To learn more about JavaScript’s parameters and arguments, Mozilla has excellent documentation.

--

--

Uriel Rodriguez
The Startup

Flatiron School alumni and Full Stack web developer.