4

In which condition will Object.prototype.toString.call(fn) === '[object Function]' and typeof fn === 'function' return different results?

I saw the function isCallable on mdn (see line 4 - line 7):

var isCallable = function (fn) {
    var toStr = Object.prototype.toString
    return typeof fn === 'function' || toStr.call(fn) === '[object Function]'
}

I'm wondering the difference between these two tests, is one of them superfluous?

djy
  • 737
  • 6
  • 14
  • Possible duplicate of [what's different between Object.prototype.toString.call and typeof](https://stackoverflow.com/questions/31459821/whats-different-between-object-prototype-tostring-call-and-typeof) – ponury-kostek Apr 03 '19 at 16:12
  • "These two functions" I only see one function. Also to improve readability, please don't put half the question in the title. – Daniel W. Apr 03 '19 at 16:14
  • 1
    @DanFromGermany The two are `typeof fn === 'function'` and `toStr.call(fn) === '[object Function]'`, also, edited the title, thanks – djy Apr 03 '19 at 16:18
  • I have no idea what this code is supposed to do – Jonas Wilms Apr 03 '19 at 16:35

1 Answers1

2

Object.prototype.toString returns the value of the object's internal [[Class]] property, it isn't really a Type.
The value of this internal property represents the specification defined classification of an object (more info here).
The value of the [[Class]] internal property for host objects -as DOM elements- can be anything, it is completely implementation-dependent.

So, the best way to test whether fn is a function is to use typeof fn.
Not only is it faster but the ECMAScript specification ensures that all functions have a type of "function" and that only functions can have a type of "function" (see also https://stackoverflow.com/a/17108198/709439).

MarcoS
  • 17,323
  • 24
  • 96
  • 174