Alternative isFunction Implementations (v2)

Revision 2 of this benchmark created on


Description

This test case compares three alternative isFunction implementations:

  • isFunctionA checks the internal [[Class]] name of an object to determine if it is a function. Unfortunately, while this check is the most reliable, it's also less efficient due to the extra call to Object#toString.
  • isFunctionB was proposed as an alternative to the typeof and instanceof operators by Garrett Smith. This implementation uses duck-typing, so it may produce incorrect results.
  • isFunctionC is currently used in Underscore.js. This implementation uses only basic duck-typing; thus, it is the most likely to produce incorrect results.

Preparation HTML

<script>
  var getClass = {}.toString,
      hasProperty = {}.hasOwnProperty,
      expression = /Kit/g;
  
  function Test() {}
  
  // Checks the internal [[Class]] name of the object.
  
  
  function isFunctionA(object) {
   return object && getClass.call(object) == '[object Function]';
  }
  
  // Partial duck-typing implementation by Garrett Smith.
  
  
  function isFunctionB(object) {
   if (typeof object != 'function') return false;
   var parent = object.constructor && object.constructor.prototype;
   return parent && hasProperty.call(parent, 'call');
  }
  
  // Pure duck-typing implementation taken from Underscore.js.
  
  
  function isFunctionC(object) {
   return !!(object && object.constructor && object.call && object.apply);
  }
</script>

Setup

var getClass = {}.toString,
          hasProperty = {}.hasOwnProperty,
          expression = /Kit/g;
      
      function Test() {}
      
      // Checks the internal [[Class]] name of the object.
      
      
      function isFunctionA(object) {
       return object && getClass.call(object) == '[object Function]';
      }
      
      // Partial duck-typing implementation by Garrett Smith.
      
      
      function isFunctionB(object) {
       if (typeof object != 'function') return false;
       var parent = object.constructor && object.constructor.prototype;
       return parent && hasProperty.call(parent, 'call');
      }
      
      // Pure duck-typing implementation taken from Underscore.js.
      
      
      function isFunctionC(object) {
       return !!(object && object.constructor && object.call && object.apply);
      }

Test runner

Ready to run.

Testing in
TestOps/sec
isFunctionA
isFunctionA(Test);
isFunctionA(getClass);
isFunctionA(hasProperty);
!isFunctionA(expression);
ready
isFunctionB
isFunctionB(Test);
isFunctionB(getClass);
isFunctionB(hasProperty);
!isFunctionB(expression);
ready
isFunctionC
isFunctionC(Test);
isFunctionC(getClass);
isFunctionC(hasProperty);
!isFunctionC(expression);
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.