Alternative isFunction Implementations with verifications and several test types (v8)

Revision 8 of this benchmark created by Max on


Preparation HTML

<script>
function closure() {
  return function() {
    return 42;
  };
}
  var
      // used in isFunction implementations
      getClass = {}.toString,
      hasProperty = {}.hasOwnProperty,

      // Test data
      noop = function(){},
      objectToString = {}.toString,
      objectHasOwnProperty = {}.hasOwnProperty,
      expression = /Kit/g,
      browserAlert = alert,
      objectConstructor = Object,
      dateConstructor = Date,
      stringConstructor = String,
      int = 12345,
      emptyStr = "",
      longStr = "abcdefghijklmnopqrstuvwxyz0123456789 abcdefghijklmnopqrstuvwxyz0123456789 abcdefghijklmnopqrstuvwxyz0123456789 abcdefghijklmnopqrstuvwxyz0123456789 abcdefghijklmnopqrstuvwxyz0123456789 abcdefghijklmnopqrstuvwxyz0123456789 abcdefghijklmnopqrstuvwxyz0123456789 abcdefghijklmnopqrstuvwxyz0123456789 abcdefghijklmnopqrstuvwxyz0123456789 abcdefghijklmnopqrstuvwxyz0123456789 abcdefghijklmnopqrstuvwxyz0123456789 abcdefghijklmnopqrstuvwxyz0123456789 abcdefghijklmnopqrstuvwxyz0123456789 abcdefghijklmnopqrstuvwxyz0123456789 abcdefghijklmnopqrstuvwxyz0123456789";
  
  // 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);
  }

  // Simple typeof comparison
  function isFunctionD(object) {
   return typeof(object) == 'function';
  }
  
  // Simple instanceof comparison
  function isFunctionE(object) {
   return object instanceof Function;
  }

var toStr = Object.prototype.toString;
  // Object.prototype.toString.call(func)
  function isFunctionF(object) {
   return toStr.call(func) == '[object Function]';
  }
  
  // Checks the internal [[Class]] name of the object.
  // (with strict equality)
  function isFunctionAb(object) {
   return !!(object && getClass.call(object) === '[object Function]');
  }

  // Simple typeof comparison
  // (with strict equality)
  function isFunctionDb(object) {
   return typeof(object) === 'function';
  }

  function benchmarkIsFunction(fnc)
  {
    fnc(noop);
    fnc(objectToString);
    fnc(objectHasOwnProperty);
    fnc(expression);
    fnc(browserAlert);
    fnc(objectConstructor);
    fnc(dateConstructor);
    fnc(stringConstructor);
    fnc(int);
    fnc(emptyStr);
    fnc(longStr);
    fnc(undefined);
    fnc(closure);
  }

  function verify(verified, fnc, name, data)
  {
    if(!verified && typeof console !== "undefined" && typeof console.error !== "undefined")
    {
      console.error(name + " failed the functionality test for data " + data);
    }
  }

  function verifyIsFunction(fnc, name)
  {
    verify(fnc(noop) === true, fnc, name, "noop");
    verify(fnc(objectToString) === true, fnc, name, "objectToString");
    verify(fnc(objectHasOwnProperty) === true, fnc, name, "objectHasOwnProperty");
    verify(fnc(expression) === false, fnc, name, "expression");
    verify(fnc(browserAlert) === true, fnc, name, "browserAlert");
    verify(fnc(objectConstructor) === true, fnc, name, "objectConstructor");
    verify(fnc(dateConstructor) === true, fnc, name, "dateConstructor");
    verify(fnc(stringConstructor) === true, fnc, name, "stringConstructor");
    verify(fnc(int) === false, fnc, name, "int");
    verify(fnc(emptyStr) === false, fnc, name, "emptyStr");
    verify(fnc(longStr) === false, fnc, name, "longStr");
    verify(fnc(undefined) === false, fnc, name, "undefined");
    verify(fnc(closure) === true, fnc, name, "closure");
    verify(fnc(closure()) === true, fnc, name, "closure()");
    verify(fnc(function(){}) === true, fnc, name, "function(){}");
  }

  verifyIsFunction(isFunctionA, "A");
  verifyIsFunction(isFunctionB, "B");
  verifyIsFunction(isFunctionC, "C");
  verifyIsFunction(isFunctionD, "D");
  verifyIsFunction(isFunctionE, "E");
  verifyIsFunction(isFunctionAb, "Ab");
  verifyIsFunction(isFunctionDb, "Db");

</script>

Test runner

Ready to run.

Testing in
TestOps/sec
isFunctionA
benchmarkIsFunction(isFunctionA)
ready
isFunctionB
benchmarkIsFunction(isFunctionB)
ready
isFunctionC
benchmarkIsFunction(isFunctionC)
ready
isFunctionD
benchmarkIsFunction(isFunctionD)
ready
isFunctionAb (strict equality)
benchmarkIsFunction(isFunctionAb)
ready
isFunctionDb (strict equality)
benchmarkIsFunction(isFunctionDb)
ready
isFunctionE
benchmarkIsFunction(isFunctionE)
ready
isFunctionF
benchmarkIsFunction(isFunctionF)
ready

Revisions

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