Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strict-Mode: Alternative to argument.callee.length?

Tags:

javascript

Javascript: The Definitive Guide (2011) has this example (p.186) that doesn't work in strict mode but does not show how to implement it in strict mode--I can think of things to try but am wondering about best practices/security/performance--what's the best way to do this sort of thing in strict mode? Here's the code:

// This function uses arguments.callee, so it won't work in strict mode.
function check(args) {
    var actual = args.length;          // The actual number of arguments
    var expected = args.callee.length; // The expected number of arguments
    if (actual !== expected)           // Throw an exception if they differ.
        throw Error("Expected " + expected + "args; got " + actual);
}

function f(x, y, z) {
    check(arguments);  // Check that the actual # of args matches expected #.
    return x + y + z;  // Now do the rest of the function normally.
}
like image 574
Adam Golding Avatar asked Apr 08 '12 23:04

Adam Golding


1 Answers

You could just pass the function you're checking.

function check(args, func) {
    var actual = args.length,
        expected = func.length;
    if (actual !== expected)
        throw Error("Expected " + expected + "args; got " + actual);
}

function f(x, y, z) {
    check(arguments, f);
    return x + y + z;
}

Or extend Function.prototype if you're in an environment that will allow it...

Function.prototype.check = function (args) {
    var actual = args.length,
        expected = this.length;
    if (actual !== expected)
        throw Error("Expected " + expected + "args; got " + actual);
}

function f(x, y, z) {
    f.check(arguments);
    return x + y + z;
}

Or you could make a decorator function that returns a function that will do the check automatically...

function enforce_arg_length(_func) {
    var expected = _func.length;
    return function() {
        var actual = arguments.length;
        if (actual !== expected)
            throw Error("Expected " + expected + "args; got " + actual);
        return _func.apply(this, arguments);
    };
}

...and use it like this...

var f = enforce_arg_length(function(x, y, z) {
    return x + y + z;
});
like image 195
4 revsuser1106925 Avatar answered Oct 24 '22 06:10

4 revsuser1106925