Hold Missing Parameters in JavaScript

When you call a function in JavaScript and you miss a parameter, nothing happens.

This makes debugging difficult, so I would like to change this behavior.

I saw It’s better to determine if the argument is passed to the JavaScript function, but I want a solution with a constant number of typed lines of code; without entering an additional code for each function.

I thought about automatically prefixing the code of all functions with this code by changing the constructor ("first-class") of the Function object.

Inspired by Changing the constructor in JavaScript I first checked if I can change the constructor of the Function object, for example:

function Function2 () {
    this.color = "white";
}

Function.prototype = new Function2();
f = new Function();
alert(f.color);

"undefined" "", , .

- ? JavaScript , , , .

+5
4

, .

Function , , (, jQuery scope undefined).

, :

1)

var foo = function (requiredParam) {
    if (typeof requiredParam === 'undefined') {
        throw new Error('You must pass requiredParam to function Foo!');
    }

    // solve world hunger here
};

2) , ( jQuery)

var foo = function (argumentObject) {
    argumentObject = $.extend({
        someArgument1: 'defaultValue1',
        someArgument2: 'defaultValue2'
    }, argumentObject || {});

    // save the world from alien invaders here
};
+9

, , , , ! !

, , ! , :

//example function
function thing(a, b, c) {

}

var functionPool = {} // create a variable to hold the original versions of the functions

for( var func in window ) // scan all items in window scope
{
  if (typeof(window[func]) === 'function') // if item is a function
  {
    functionPool[func] = window[func]; // store the original to our global pool
    (function(){ // create an closure to maintain function name
         var functionName = func;
         window[functionName] = function(){ // overwrite the function with our own version
         var args = [].splice.call(arguments,0); // convert arguments to array
         // do the logging before callling the method
         if(functionPool[functionName].length > args.length)
              throw "Not enough arguments for function " + functionName + " expected " + functionPool[functionName].length + " got " + args.length;                     
         // call the original method but in the window scope, and return the results
         return functionPool[functionName].apply(window, args );
         // additional logging could take place here if we stored the return value ..
        }
      })();
  }
}

thing(1,2 ,3); //fine
thing(1,2); //throws error

:

, , Function.prototype.call. , , . , Function , , eval ! , , , , , . , , , , .

, , javascript - , -, , .

+2

. , , .

/* Wrap the function *f*, so that *error_callback* is called when the number
   of passed arguments is not with range *nmin* to *nmax*. *error_callback*
   may be ommited to make the wrapper just throw an error message.
   The wrapped function is returned. */
function require_arguments(f, nmin, nmax, error_callback) {
    if (!error_callback) {
        error_callback = function(n, nmin, nmax) {
            throw 'Expected arguments from ' + nmin + ' to ' + nmax + ' (' +
                  n + ' passed).';
        }
    }
    function wrapper() {
        var n_args = arguments.length;
        console.log(n_args, nmin, nmax);
        console.log((nmin <= 0) && (0 <= nmax));
        if ((nmin <= n_args) && (n_args <= nmax)) {
            return f.apply(this, arguments);
        }
        return error_callback(n_args, nmin, nmax);
    }
    for (e in f) {
        wrapper[e] = f[e];
    }
    return wrapper;
}


var foo = require_arguments(function(a, b, c) {
    /* .. */
}, 1, 3);
foo(1);
foo(1, 2);
foo(1, 2, 3);
foo(1, 2, 3, 4); // uncaught exception: Expected arguments from 1 to 3 (4 passed).
foo(); // uncaught exception: Expected arguments from 1 to 3 (0 passed).
+1

- Pythons. , .

function force(inner) {
    return function() {
        if (arguments.length === inner.length) {
            return inner.apply(this, arguments);
        } else {
            throw "expected " + inner.length +
                " arguments, got " + arguments.length;
        }
    }
}

var myFunc = force(function(foo, bar, baz) {
    // ...
});

All in all, this sounds like a bad idea because you mostly mess with the language. Do you really forget to pass arguments often?

+1
source

All Articles