Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use typeof for identifying a function?

Tags:

javascript

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

like image 949
samshull Avatar asked Feb 20 '11 00:02

samshull


4 Answers

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.

like image 179
user113716 Avatar answered Sep 18 '22 09:09

user113716


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.

like image 37
Gumbo Avatar answered Sep 18 '22 09:09

Gumbo


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"
like image 37
3 revs, 2 users 88%user166390 Avatar answered Sep 19 '22 09:09

3 revs, 2 users 88%user166390


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!

like image 34
Raynos Avatar answered Sep 21 '22 09:09

Raynos