isFunction() or isObject(), that is the question ?

In my previous post, we have established few simple rules and presented a simple mechanism for dealing with object “roles” in JavaScript. In the same time we have consluded that isFunction() and isObject() will not be that “trivial” to implement in IE.

Here is the simple requirement: write a function that will return true if argument given is a function. Hint: In IE, typeof window.alert , returns “object”

Here is my portable isFunction() :

It works all the time and everywhere. Everybody enjoy? How about passing it this :

Well … above version does not work that well. Here is the (hopefully) proper version :

Is this little “hack” breakable ? Well it is, if given this :

Oh well , how about this new version then :

Is this it then? The wholy grail of javascript? An universal isFunction() ?
No it is not .. yet. Above (x + "")will fail if this is given as an argument to isFunction(x) :

So, here we go again, with yet another version :

Of course here I am concerned primarily with the solution.
For the above optimizations are certainly possible and are left as an “excersize to the reader” 😉

At last…?

Wait there is more … Verion 5. Seems slightly ridiculous, but it also seems to work (almost) perfectly.

See the comment bellow explaining the single case which brakes V.5. In any case, we have a solution for determining if object is a function (aka “callable”). which leaves yet another “tough cooky” for IE “side” : isObject(). Which will return trues or false , if argument given is object or not. So in the IE this must be false :

With the help of isFunction() we can build isObject(), for IE, that will also work properly. We will simly check first if argument is a function. If it is it can not be object in the same time. Here is the working code :

Update 2012 Oct 08
Please consider this code released under the MIT licence.


NOTE: this post was also inspired with: http://webreflection.blogspot.com/2009/08/isfunction-hacked-iscallable-solution.html

7 Replies to “isFunction() or isObject(), that is the question ?”

  1. [code]
    alert(isFunction({toString:function(){return "function"}}));
    // true in every IE
    [/code]

    As already discussed, the [code]Object.prototype.toString.call(x) === "[object Function]"[/code] is the best way so far to know if that function is usable as every other function. In IE only you can have problems with native function so you would like to know if these are IE native function and again, as already posted, this is my snippet:

    [code]
    function isIENativeFunction(f){
    return !!f && typeof f.toString === "undefined" && /^\s*\bfunction\b/.test(f);
    };

    alert(isIENativeFunction(alert));
    [/code]

  2. Sorry Andrea, but your “solution” will not work with this argument :
    [code]
    isIENativeFunction(
    { toString : undefined, valueOf : function () { return "function X";} }
    )
    /*
    returns: true
    */
    [/code]
    And it will throw an exception in this case :
    [code]
    isIENativeFunction({ toString : undefined })
    /*
    TypeError
    Number : 438
    Description : Object doesn’t support this property or method
    */
    [/code]
    Etc … I am sure, by now, you have spoted the flaw in your logic. But thanks for your comment, anyway.

  3. There is a solution , which *should* work “everywhere, and which fails on *only* one singularity.
    There is only one “bomb” which is hardly possible in reality, unless someone “plants” it deliberately. For *every* other case this simple function bellow should work.

  4. Thanks @Chris … Valid question is:

    is that a valid use case ? But anyway here is the solution to “something” calling with this kind of “clever” string:

Comments are closed.