HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Type / Constructor testing utilities

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
typeconstructortestingutilities

Problem

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;
}

Solution

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.

Code Snippets

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;
}
// 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]
        : '';
}

Context

StackExchange Code Review Q#18372, answer score: 3

Revisions (0)

No revisions yet.