Are there any significant reasons for using
typeof variable === 'function'
versus
!!variable.call
for detecting if a variable is a function?
Other than the obvious one that someone may create an object like:
{ call: 1 }
The problem that I have is that
typeof /regex/ === 'function'
returns true, but
!!/regex/.call
returns false
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.
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.
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"
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With