Why use typeof for identifying a function?

后端 未结 6 593
天涯浪人
天涯浪人 2020-12-09 13:03

Are there any significant reasons for using

typeof variable === \'function\'

versus

!!variable.call

for d

相关标签:
6条回答
  • 2020-12-09 13:27

    jQuery's isFunction avoids the RegExp problem you mention by toString-ing the object and checking the result against a map of known types. From the latest source, here's the map:

    // Populate the class2type map
    jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
        class2type[ "[object " + name + "]" ] = name.toLowerCase();
    });
    

    And here's how it's used:

    type: function( obj ) {
        return obj == null ?
            String( obj ) :
            class2type[ toString.call(obj) ] || "object";
    },
    
    // See test/unit/core.js for details concerning isFunction.
    // Since version 1.3, DOM methods and functions like alert
    // aren't supported. They return false on IE (#2968).
    isFunction: function( obj ) {
        return jQuery.type(obj) === "function";
    },
    

    You can learn a lot reading the jQuery source.

    • http://james.padolsey.com/jquery/#v=1.5.0&fn=jQuery.isFunction
    • http://james.padolsey.com/jquery/#v=1.5.0&fn=jQuery.type
    0 讨论(0)
  • 2020-12-09 13:28

    The safest way is to check the internal [[Class]] property by setting the object as the thisArg argument of the .call() method when calling Object.prototype.toString.

    Object.prototype.toString.call( myVariable ) === '[object Function]';
    

    Of course you could easily make a function out of it:

    function checkClass( obj ) {
        return Object.prototype.toString.call( obj ).slice( 8, -1).toLowerCase();
    }
    
    checkClass( myVariable ) === 'function';
    

    This is very simple, and there could be some improvements, but you get the idea.

    0 讨论(0)
  • 2020-12-09 13:34

    typeof variable === 'function' is better than !!variable.call because if variable is undefined or null, !!variable.call will throw an error.

    0 讨论(0)
  • 2020-12-09 13:36

    According to the ECMAScript specification, the following should apply for regular expression literals:

    A regular expression literal is an input element that is converted to a RegExp object (section 15.10) when it is scanned. The object is created before evaluation of the containing program or function begins.

    So typeof /regex/ should yield "object":

    typeof /regex/ === "object"
    

    And the constructor of the object created by the regular expression literal should be RegExp:

    /regex/.constructor === RegExp
    

    Similar to that, a function definition should yield a Function object:

    (function(){}).constructor === Function
    

    But although this returns a Function object, the typeof operator should not yield "object" but "function" instead:

    typeof function(){} === "function"
    

    This is due to the distinction whether the object implements the internal [[Call]] property that is special for Function objects.

    Note that all this is how Javascript implementations should behave. So all equations are asserted to be true.

    0 讨论(0)
  • 2020-12-09 13:36

    A regular expression is a function

    /bar/("bar") === ["bar"]

    So typeof /bar/ === "function"

    Although only chrome recognises that a regexp literal can be used as a function. Whether this should be so or not is up for grabs. You can treat it just like a function!

    0 讨论(0)
  • 2020-12-09 13:41

    Check the assumptions in the post (see Gumbo's comment).

    typeof /regex/ === 'function'
    

    This returns false in Firefox 3.6.13.

    Just for amusement, Firefox 3.6.13:

    typeof /regex/                    // "object"
    /regex/ instanceof RegExp         // true
    /regex/.constructor.name          // RegExp
    (function () {}).constructor.name // Function
    

    IE8:

    typeof /regex/                    // "object"
    /regex/ instanceof RegExp         // true
    /regex/.constructor.name          // undefined
    (function () {}).constructor.name // undefined
    

    Chrome 9:

    typeof /regex/                    // "function"
    /regex/ instanceof RegExp         // true
    /regex/.constructor.name          // "RegExp"
    (function () {}).constructor.name // "Function"
    
    0 讨论(0)
提交回复
热议问题