Optional argument first in JavaScript

For the convenience of the user, I have a function that first receives an optional argument, before the necessary argument. For instance:

ns.myFunction('optional arg', function(){
    //the required callback
});

I am doing this, and not doing the following, since the callback body can be long and the user may forget to override the default values ​​for optional arguments:

ns.myFunction(function(){
    //the required callback
}, 'optional arg');

I am currently doing this to check:

function myFunction(first, second) {

    //if second is undefined and first is a function
    if (typeof second === 'undefined' && typeof first === 'function') { 
        second = first;
    }
}

Questions

  • Is it correct?
  • How can I make it scaled, especially if there were N optional arguments that are before the required argument?
+7
source share
7 answers

, . : . , API :

function callback1() { //...

var callback2 = function() {//...

myFunction(callbackX, optional);

this bind().

, : arguments options.

arguments :

var lastOptionalIndex = arguments.length - 2;
var callback = arguments[lastOptionalIndex + 1];  //required callback is always last
var optionalFirst = lastOptionalIndex >=0? arguments[0] : undefined;
var optionalSecond = lastOptionalIndex >=1? arguments[1] : undefined;
//...

, :

function myFunction(callback, firstOptional, secondOptional //...

- options :

function myFunction(options, callback);

options :

{
  firstOptional: 1,
  secondOptional: 'foo'
  //...
}
+3

ArgueJS:

function myFunction (){
  arguments = __({first: [String], second: Function})

  // and now on, you can access your arguments by
  //   arguments.first and arguments.second
}

ArgueJS. , :

function range(){ 
  arguments = __({start: [Number, 0], stop: Number, step: [Number, 1]})

  for(var i = arguments.start; i < arguments.stop; i += arguments.step)
    console.log(i);
}

:

>>> range(3)
 0
 1
 2
>>> range(3, 5)
 3
 4
>>> range(0, 5, 2)
 0
 2
 4
+2

- . :

if (arguments.length < 2)  // There are no optional parameters

[i]. [arguments.length - 1].

typeof , == ===

+1

ArgueJS:

function range(){ 
  arguments = __({start: [Number, 0], stop: Number, step: [Number, 1]});
  for(var i = arguments.start; i < arguments.stop; i += arguments.step)
    console.log(i);
}

ES6:

function range(){ 
  {start, stop, step} = __({start: [Number, 0], stop: Number, step: [Number, 1]})
  for(var i = start; i < stop; i += step)
    console.log(i);
}

CoffeeScript:

range = ->
  {start, stop, step} = __ {start: [Number, 0], stop: Number, step: [Number, 1]}
  console.log i for i in [start...stop] by step
+1

:

myFunction() {
    let first, second;
    if (arguments.length === 2) {
        [first, second] = arguments;
    } else if (arguments.length === 1) {
        [second] = arguments;
    }
    if ( ! first) {
        // first is undefined, so only second argument was passed.
    }
}

ES6 .

+1

, :

function myFunction() {
    alert("optional:");
    for(var i=0; i<arguments.length-1) alert(arguments[i]);
    alert("function: "+ arguments[arguments.length-1]);
}

But that is pretty ugly. I think you should just add extra material at the end.

0
source

Simple functional approach:

/**
* @param {function} fn(a,...b)
* @param {function} argumentTest - a function to test the first parameter
* @return {function} returns a function that passes its first argument into argumentTest. If argumentTest returns true, fn is called with the first argument shifted to the last position else fn is called with the arguments order unchanged
*/
function appendFirstArgumentIf (fn,argumentTest){
   return function(a,...b){
       return argumentTest(a) ? fn(...b,a) : fn(a,...b) 
   }
}

using:

function myFunction(callback, string){
    string = string ? string : 'Default Message'
    callback(string)
}

var myNewFunction = appendFirstArgumentIf(myFunction,
                                          firstArgument=> typeof firstArgument !== 'function')


myNewFunction('New Message', console.log)  // using console.log as callback function
//>>>New Message
myNewFunction(console.log)
//>>>Default Message

also possible with this:

function mySecondFunction(callback, name, string){
string = string ? string : 'Welcome'
callback(string, name)
}

var myLatestFunction = appendFirstArgumentIf(mySecondFunction,
                                      firstArgument=> typeof firstArgument !== 'function')


myLatestFunction('Hello', console.log, 'John')
//>>>Hello John
myLatestFunction(console.log, 'John')
//>>>Welcome John
0
source

All Articles