Published 2021-05-09 by Michael Ward

Objects as parameters in JavaScript

Objects as parameters in JavaScript

Why use an object argument?

There are some issues with the way JavaScript function and method calls are made, mostly because JavaScript lacks the ability to specify named arguments.

How named arguments work

Consider the following basic method:

function myMethod(param1, param2, param3 = "default1", param4 = "default2") {
  // function code
}

The first two method parameters are required, the next two have default values, making them optional.

Were named arguments a thing in JavaScript, the method could be called in the following ways:

myMethod(param1 = "arg1", param2 = "arg23") // Required arguments only
myMethod(param1 = "arg1", param2 = "arg23", param3 = "arg3") // Required arguments, plus one optional argument
myMethod(param1 = "arg1", param2 = "arg23", param4 = "arg") // Required arguments, plus the other optional argument
myMethod(param1 = "arg1", param2 = "arg23", param3 = "arg3", param4 = "arg4") // All arguments
myMethod(param4 = "arg4", param3 = "arg3", param1 = "arg1", param2 = "arg23" ) // All arguments, in a different order

The parameter names are supplied in the method call as named argument. This means it is possible to call the method with the arguments in any order, and any or all of the optional arguments can be omitted.

How JavaScript methods work

Using the same example as above:

function myMethod(param1, param2, param3 = "default1", param4 = "default2") {
  // function code
}

JavaScript imposes some limitations because it does not support named arguments.

The method call must specify the arguments in the same order as the parameters are defined in the function definition:

myMethod("arg1", "arg23") // OK. Required arguments only
myMethod("arg1", "arg23", "arg3") // OK. Required arguments, plus the first optional argument
myMethod("arg1", "arg23", "arg3") // NOT OK. Required arguments, plus only the second optional argument
myMethod("arg1", "arg2", "arg3", "arg4") // All arguments
myMethod(param4 = "arg4", param3 = "arg3", param1 = "arg1", param2 = "arg23" ) // All arguments, in a different order

Many scripting languages support named arguments. Named arguments allow specific parameters to be specified as arguments.

// THIS CODE IS NOT VALID JAVASCRIPT
myMethod(param1 = "arg1", param2 = "arg2", param4 = "arg3")

// THIS CODE IS NOT VALID JAVASCRIPT
myMethod(param1 = "arg1", param2 = "arg2", param4 = "arg3")

When using a named argument, the interpreter / compiler knows which paramaters will be passed values, allowing arguments to be supplied in whichever order is convenient to the developer. There is no such support in JavaScript / ECMAScript or TypeScript.

This example of fictional named parameters in JavaScript shows how an argument could specify the name of the parameter that values are being passed to.

Named parameters eliminate any need to know the order of declaration of the parameters in the function signature, and means some or all optional parameters may be skipped without issue. The name of the argument is also specified in the function call, which aids code clarity.

Simulating named parameters

Whatever the reason for a lack of support for named parameters in JavaScript, there is an alternative. JavaScript can do a reasonable job of simulating named parameters using an object parameter.

function myMethod(params) {
  console.log(params.param1)
  console.log(params.param2)
}
myMethod({param1: "arg1", param2: "arg2"})

Using an object literal to pass parameters created named data: value pairs. These pairs are perfect to replicate name parameters, they name the parameter, they don't place any significance on the order in which they're supplied and the pattern allows any or all the optional parameters to be omitted.

Object parameters free the developer from requiring detailed knowledge of the function signature and increases the readability of the code.

Destructuring with ECMAScript 6

Furthermore, using ES6 destructuring syntax (in an environment that supports ES6 destructuring ) means that object properties can be unpacked and referenced as local variables, rather than using object dot notation. Additionally, it is now possible to supply default parameter values inside the function signature.

function myMethod({param1, param2, param3 = "default1", param4 = "default2'}) {
  console.log(param1)
  console.log(param2)
  console.log(param3)
  console.log(param4)
}

myMethod({param1: "arg1", param2: "arg2"})

The pattern carries all the benefits of vanilla JavaScript functions as well as all the benefits of named parameters.

Copyright © 2021-2024 Michael Ward