简体   繁体   中英

Function with first argument being optional and dynamic

I have a function

 functionName(...arrayOfArguments, { test:"test }){}

Sometimes I have arrayOfArguments but sometimes it is just null . I would like to make this function dynamic so if arrayOfArguments has any length it should look like above but if arrayOfArguments is null I would like to do not pass it and just pass second argument like:

 functionName({ test:"test }){}

How can I make it dynamic so it will pass array if it exists but will not pass this first argument if it doesn't?

If I just do:

functionName(...arrayOfArguments, { test:"test }){}

and arrayOfArguments is null it will just pass null there as a first argument. How can I define those arguments?

If arrayofArguments is null , you can't use iterable spread on it; you'll have to use arrayOfArguments ?? [] arrayOfArguments ?? [] to make the call in order to avoid an error. That will result in no arguments for that array being passed to functionName (followed by the object with the test property).

So that means one option is that the function should expect zero or more arguments followed by the object with the test property argument at the end. You can define functionName to support that by gathering up all of its arguments into an array then popping the object off the end of the array:

 function functionName(...theArray) { const obj = theArray.pop(); console.log(`theArray has ${theArray.length} elements; obj.test = ${obj.test}`); } function example(arrayOfArguments) { functionName(...arrayOfArguments ?? [], { test:"test" }); } example(null); example([]); example(["a"]); example(["a", "b"]);

Another option is to move the object at the end to the beginning. You still need ?? [] ?? [] , but it makes the function a bit simpler:

 function functionName(obj, ...theArray) { console.log(`theArray has ${theArray.length} elements; obj.test = ${obj.test}`); } function example(arrayOfArguments) { functionName({ test:"test" }, ...arrayOfArguments ?? []); } example(null); example([]); example(["a"]); example(["a", "b"]);

Finally, you could just pass arrayOfArguments into the function directly, rather than spreading it out:

 function functionName(theArray, obj) { console.log(`theArray ${theArray ? `has ${theArray.length} elements` : "is null"}; obj.test = ${obj.test}`); } function example(arrayOfArguments) { functionName(arrayOfArguments, { test:"test" }); } example(null); example([]); example(["a"]); example(["a", "b"]);

Does it need to be two parameters? I think you could handle this scenario using an object parameter as the following:

 const functionName = ({ arrayOfArguments, testParam }) => { if (arrayOfArguments != undefined && arrayOfArguments != null) { // code if arrayOfArguments is defined and not null } else { // code if arrayOfArguments is either undefined or null } console.log('arrayOfArguments', arrayOfArguments); console.log('testParam', testParam); }; functionName({ testParam: { "test": "test" } }); functionName({ arrayOfArguments: null, testParam: { "test": "test" } }); functionName({ arrayOfArguments: ['a', 'b'], testParam: { "test": "test" } });

If handling a single object parameter does not fit your requirement then evaluating for a null (and/or undefined) arrayOfArguments like @deceze mentioned should do the trick.

You can expose a public function that accepts the array and inside of this function you can declare a private function which is the one with the logic.

 function publicFn(array) { const privateFn = (obj, nestedArray) => console.log(`array with ${nestedArray.length} elements and the obj.test === ${obj.test}`); privateFn({ test: "test" }, array || []); } publicFn(); publicFn(null); publicFn([]); publicFn(["a"]); publicFn(["b"]); publicFn(["a", "b"]);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM