为什么使用typeof来识别函数?

时间:2011-02-20 00:05:09

标签: javascript

使用

是否有任何重要原因
typeof variable === 'function'

!!variable.call

用于检测变量是否为函数?

除了显而易见的人之外可能会创建一个像:

{ call: 1 }

我遇到的问题是

typeof /regex/ === 'function'

返回true,但

!!/regex/.call

返回false

6 个答案:

答案 0 :(得分:10)

最安全的方法是在调用.call()时通过将对象设置为Object.prototype.toString方法的 thisArg 参数来检查内部[[Class]]属性。

Object.prototype.toString.call( myVariable ) === '[object Function]';

当然,您可以轻松地创建一个功能:

function checkClass( obj ) {
    return Object.prototype.toString.call( obj ).slice( 8, -1).toLowerCase();
}

checkClass( myVariable ) === 'function';

这很简单,可能会有一些改进,但你明白了。

答案 1 :(得分:5)

根据ECMAScript规范,以下内容适用于regular expression literals

  

正则表达式文字是在扫描时转换为 RegExp 对象(section 15.10)的输入元素。在评估包含的程序或函数开始之前创建该对象。

因此typeof /regex/应该产生"object"

typeof /regex/ === "object"

正则表达式文字创建的对象的构造函数应该是 RegExp

/regex/.constructor === RegExp

与此类似,function definition应该会产生 Function 对象:

(function(){}).constructor === Function

但是,虽然这会返回 Function 对象,但typeof operator不应该产生"object",而应该产生"function"

typeof function(){} === "function"

这是因为对象是否实现了internal [[Call]] property特有的Function objects

请注意,所有这些都是Javascript实现 的行为方式。所以所有方程式都被认为是真的。

答案 2 :(得分:2)

检查帖子中的假设(参见Gumbo的评论)。

typeof /regex/ === 'function'

这将在Firefox 3.6.13中返回false

只是为了娱乐,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"

答案 3 :(得分:2)

正则表达式是一个函数

/bar/("bar") === ["bar"]

所以typeof /bar/ === "function"

虽然只有chrome识别出可以将regexp文字用作函数。是否应该这样做是可以争取的。你可以像对待一个功能一样对待它!

答案 4 :(得分:1)

jQuery's isFunction避免了RegExp提到的toString问题 - 对象并根据已知类型的地图检查结果。从latest source开始,这是地图:

// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
    class2type[ "[object " + name + "]" ] = name.toLowerCase();
});

以下是它的使用方法:

type: function( obj ) {
    return obj == null ?
        String( obj ) :
        class2type[ toString.call(obj) ] || "object";
},

// See test/unit/core.js for details concerning isFunction.
// Since version 1.3, DOM methods and functions like alert
// aren't supported. They return false on IE (#2968).
isFunction: function( obj ) {
    return jQuery.type(obj) === "function";
},

你可以学习很多阅读jQuery源代码。

答案 5 :(得分:-1)

typeof variable === 'function'优于!!variable.call,因为如果变量未定义或为null,!!variable.call将引发错误。