0

I have a js file with an imported default options and function as below. I am trying to get all the arguments in the function, however it appears that they cannot be used.

import {defaultOptions} from "../defaults.js"

export function getConfig({
  width = defaultOptions.width,
  height = defaultOptions.height,
  fontsize = defaultOptions.fontsize
} = {}) {
   console.log(width); //shows width

   // I want to get all the arguments 
   console.log(arguments); 
}

When I call the function with no parameters like getConfig() and console.log(width) then it shows the width from the defaultOptions from the defaults.js. However the console.log(arguments) returns Arguments object with length 1 where index 0 : undefined.

Is there a way I can get all the arguments in such a function?

Update: See this JSFiddle for something similar where defaults are specified earlier that the function for example. https://jsfiddle.net/coolakul/fa9muzwh/8/

Coola
  • 2,934
  • 2
  • 19
  • 43

3 Answers3

2

Arguments vs. Parameters

For this question, it's important to distinguish between arguments and parameters. Arguments are what is passed to the function when it's invoked, without consideration for how the function destructures or sets defaults to those values. So when you call getConfig() with no arguments, and log arguments.length, it should be 0, regardless of how getConfig destructures or sets defaults.

Parameters on the other hand are the variables in the function definition, that it uses. They can be assigned defaults or they can be derived from a destructured argument.

It's a little unclear what you're looking for, whether it's an object that reflects the parameters that the function uses or whether it's an object that reflects the values passed to the function (including destructured undefined variables). I'll go over both cases.

Parameters

To reconstitute the parameters, a rather clunky way is to use the destructured variables into a new object:

import {defaultOptions} from "../defaults.js"

export function getConfig({
  width = defaultOptions.width,
  height = defaultOptions.height,
  fontsize = defaultOptions.fontsize
} = {}) {
  // just assign them to parameters
  var parameters = { width, height, fontsize };
  console.log(parameters); 
}

Alternatively, if defaultOptions represents all of and only the parameters passed to the function (i.e. it only has width, height, fontsize), you can assign them with spread syntax:

import {defaultOptions} from "../defaults.js"

export function getConfig(options = {}) {
   var calculatedParameters = { ...defaultOptions, ...options };
   var { width, height, fontsize } = calculatedParameters;
   console.log(calculatedParameters); 
}

Values passed to the function (including destructured undefined variables)

To reconstitute the values passed, you can destructure the argument and then assign it again to a variable. This variable is nearly identical to the argument itself. In the below example calculatedArguments is almost identical to options, except now it will have properties for width, height, and fontsize, even if they represent undefined values:

import {defaultOptions} from "../defaults.js"

export function getConfig(options = {}) {
   var { width, height, fontsize } = options;
   var calculatedArguments = { width, height, fontsize };
   console.log(calculatedArguments); 

   // can also assign width, height, fontsize with default values
   ({
      width = defaultOptions.width,
      height = defaultOptions.height,
      fontsize = defaultOptions.fontSize
    } = options);
}
Steve
  • 10,435
  • 15
  • 21
  • 2
    Thanks for the detailed answer. This resolves my issues. I can give bounty after a few hours. – Coola Feb 24 '22 at 16:09
1
let defaults = {
  width: 300,
  height: 500,
  symbsize: 25,
  margin: {
    top: 10,
    bottom: 10
  }
}

class Config {
    constructor({
      width = defaults.width, 
      height = defaults.height, 
      symbsize = defaults.symbsize, 
      margin = defaults.margin
    } = defaults) {
      this.width = width
      this.height = height
      this.symbsize = symbsize
      this.margin = margin
    }
  
  getConfig() {
    return {
      width: this.width,
      height: this.height,
      symbsize: this.symbsize,
      margin: this.margin
    }
  }
}

const config = new Config({height: 1})

console.log(config.getConfig());

using class should do the work, or i prefer using it

  • While this is a good solution, it is not what I am looking for. I have up voted it as it might be applicable to other's project design requirements. – Coola Feb 25 '22 at 00:54
0

If I am not mistaken, try this :

import { defaultOptions } from "../defaults.js";

export function getConfig(arguments = {}) {
  const { width, height, fontsize } = arguments;
  console.log(width);
  console.log(arguments);
}
getConfig(defaultOptions);
Achraf
  • 111
  • 8
  • I don't think this is the solution. The reason being I do not want to pass defaultOptions as an argument. It should be there by default and when the getConfig is called the user can override these options like `getConfig({width: 300})`. In this case the default option of width will be overridden by the passed parameter of 300. – Coola Feb 21 '22 at 00:54