'Is `typeof foo === 'function'` the only way (other than attempting to call the object) to determine whether an object is callable?
Is typeof foo === 'function' the only way (other than attempting to call the object) to determine whether an object is callable?
If so, is this because it is otherwise impossible to distinguish between a callable object and an object that merely inherits from Function.prototype?
I note that until ES2015, the only way (other than supplying a string to Function, and possibly eval) to create a callable object, was to use the function () {} syntax, to create a function-object directly; and that ES2015 introduced a way of extending exotic objects like Function, enabling callable objects to be configured using the class CallableClass extends Function syntax, and instantiated using the new CallableClass syntax.
To restate: For all objects, typeof returns 'object' EXCEPT for callable function-objects, for which it returns 'function'. Is this the singular language feature, deliberately included, to enable userland identification of callable objects (because there was no other way)?
Solution 1:[1]
Yes.
typeof was added to the language in JavaScript 1.1 (codified June, 1997).
A predicate to determine callability was rejected in favour of a tweaked typeof (to return 'function' for callable objects) on the basis of parsimony. A callable object was defined as being "native" (presumably not "host" (eg browser) or "foreign" (eg. Java interop.)?), and implementing the internal [[Call]] method.
Thus: typeof returns 'object' for every native object in JavaScript, except callable native objects, for which it returns 'function'.
Note that:
Exotic non-standard objects are permitted to return other values, but the value returned must not match any of the values used in the specification (
'undefined','object','function', etc.).There is also the
document.allanomaly, but, of course,document.allis part of the Web platform and not JavaScript .
From the JavaScript 1.1 specification:
Since the internal [[Call]] method is not directly visible to userland code; and since [[Call]] cannot be configured on an existing object by simply running the Function constructor against an existing object; and since adding Function.prototype to the prototype chain of an existing object is insufficient, there are only two ways of determining callability:
- Attempt to run the object as a function
- Use
typeof === 'function'
Me:
Was this because there was no other userland way to distinguish between a callable object created using
function foo(){}and a non-callable object that merely inherited fromFunction.prototype? Or that perhaps there was a way, but that it was inconvenient?
Brendan Eich:
Yes, and we anticipated foreign (Java, lol) objects and "host objects" that had callable objects which weren't native JS functions. I was adding typeof in Netscape 3 (JS1.1) so rather than a callable predicate, parsimonious to extend typeof slightly.
Solution 2:[2]
I think it would execute that statement given the chance, but you are breaking out of the while loop too soon.
Specifically, you have an unnecessary break statement immediately after the else {return -1;} . That break statement stops the search after the first binary cut, so get rid of it.
Offhand, i think there are further issues with your algorithm, that might lead to infinite loops - eg if the search value is not present, etc. So compare your code against other references - eg even https://en.m.wikipedia.org/wiki/Binary_search_algorithm will do for this (*)
(*) apologies to any Wikipedia proponents !
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |

