Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

My argument sanitization lib has a byproduct which does some typechecking and constructor investigation. I'm unsure if I'm using the fastest / most efficient approach here.

What are your opinions? Total rubbish or does it have a right to exist? ;)

// Return the type of an object aka safe typeof
function typeOf(o) {
    return Object.prototype.toString.call(o).match(/(\w+)\]/)[1];
}

// Return the name of a function aka class name
function nameOf(o) {
    return typeOf(o) == "Function"
        ? Function.prototype.toString.call(o).match(/function\s?(\w*)\(/)[1]
        : false;
}

// Return the expected arguments of a function
function argumentsOf(o) {
    if(typeOf(o) == "Function") {
        var args = Function.prototype.toString.call(o).match(/\((.+)\)\s*{/);
        if(!!args && !!args[1]) return args[1].replace(/\s+/g, "").split(",");
        else return [];
    } else return false;
}
share|improve this question
2  
You could return the string "anonymous" instead of false for a function name. Also it will throw an error for [1] because .match() can return null –  Esailija Nov 9 '12 at 0:41
    
I prefer false. Are there any substantial benefits? –  silvinci Nov 9 '12 at 6:17
    
Function should always match the pattern and [1] should therefore always match. But just to be safe, I'll check that. Thanks. –  silvinci Nov 9 '12 at 6:19
    
false is not a string, though returning an empty string is viable as well. Getting a boolean from a function named nameOf is kinda iffy :P –  Esailija Nov 9 '12 at 11:42
    
I think we got something twisted here: falseis returned when no function was given and nameOf doesn't know what to do. "" is returned when there is no function name. I think it's safer than "anonymous", because some weird users might name their function anonymous and then things would blow up. –  silvinci Nov 9 '12 at 21:04
show 1 more comment

1 Answer

Fun question,

I believe the only reliable way of getting the name and parameters of a function is to indeed parse the toString. However, you can figure out whether the parameter is a function without a regex. I would propose from here :

function isType(object, type){
     return object != null && type ? object.constructor.name === type.name : object === type;
}

// Return the name of a function aka class name
function nameOf(o) {
    return isType( o , Function )
        ? Function.prototype.toString.call(o).match(/function\s?(\w*)\(/)[1]
        : false;
}

There are still a few things that bother me here, why is the parameter name o, which is the Spartan convention for Object whereas we expect a function ? Also, why name the function nameOf, which creates an expectation of being to name anything whereas it really only can give the name for a function, maybe it ought to be called nameOfFunction or functionName(). Finally, as per the comments, making a function with name return false is making the name lie, just return ''. Something like this then:

// Return the name of a function aka class name
function functionName(f) {
    return isType( f , Function )
        ? Function.prototype.toString.call(f).match(/function\s?(\w*)\(/)[1]
        : '';
}

Finally, for argumentsOf, I sincerely dislike dropping the newline in if statements, removing curly braces is fine, but no newlines makes it too hard to read.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.