1

Say I have a function whose first parameter is used differently depending on how many arguments are passed. In this case, it is easier to just process the arguments object as a whole within the function definition instead of giving the parameter an explicit name to deal with that could be semantically incorrect depending on how many arguments there are, and then having to correct it after-the-fact. However, after defining the function, I want its length property to indicate that it does require at least one argument.

A point in case is the following function:

function validateSlice() {
  const range = [...arguments].map(Number)

  if (range.length < 1 || 3 < range.length) {
    throw new TypeError('expected between 1 and 3 arguments')
  }

  if (range.some(isNaN)) {
    throw new TypeError('arguments must be numeric')
  }

  switch (range.length) {
  case 1: return [0, ...range, 1]
  case 2: return [...range, 1]
  case 3:
    if (range[2] === 0) {
      throw new RangeError('slice step cannot be zero')
    }

    return range
  }
}

This is supposed to return an array of length === 3 containing [start, stop, step], but the first argument could be stop or start depending on how many arguments are passed.

My concern is that checking validateSlice.length returns 0 since there are no named parameters in the definition, but this is semantically incorrect. In JavaScript convention, this property indicates the minimum amount of required arguments for the function. However, it feels cumbersome to have to do something like this:

Object.defineProperty(validateSlice, 'length', { configurable: true, value: 1 })

And providing an unused named parameter seems superfluous or even misleading for maintenance (and some linting conditions), and for the reason above as I said, given its usage is dependent on the amount of arguments passed.

How would one normally resolve this issue?

1

Assuming a function that can be called as either

function (arg1, arg2, arg3)

or

function (arg1, arg3)

My approach to is follows

function(arg1, arg2, arg3){
  if(arg3 === undefined){
    let arg3 = arg2;
  }

  // continue logic
}
1

Use the arguments keyword to get all of the arguments in a single object.

Then define a single required argument and use rest parameters (preceded with ...) for the optional arguments.

Within your code, you can ignore required, since it will be the same as arguments[0].

function ( required, ...optional )
{
    alert("A total of " + arguments.length + " arguments were passed.");
    alert("Of those, " + optional.length + " were optional arguments.");
  • Javascript uses .length, not .Length. – David Conrad Jun 30 '18 at 0:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.