Javascript 为什么使用typeof来标识函数?

Javascript 为什么使用typeof来标识函数?,javascript,Javascript,是否有任何重要的原因使用 typeof variable === 'function' 对 !!variable.call 用于检测变量是否为函数 除了有人可能会创建如下对象的明显原因外: { call: 1 } 我的问题是 typeof /regex/ === 'function' 返回true,但是 !!/regex/.call 返回false检查帖子中的假设(参见Gumbo的评论) 这将在Firefox 3.6.13中返回false 只是为了好玩,Firefox 3.6.13:

是否有任何重要的原因使用

typeof variable === 'function'

!!variable.call
用于检测变量是否为函数

除了有人可能会创建如下对象的明显原因外:

{ call: 1 }
我的问题是

typeof /regex/ === 'function'
返回true,但是

!!/regex/.call

返回false

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

这将在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:

铬9:

typeof /regex/                    // "function"
/regex/ instanceof RegExp         // true
/regex/.constructor.name          // "RegExp"
(function () {}).constructor.name // "Function"

最安全的方法是在调用
object.prototype.toString
时,通过将对象设置为
.call()
方法的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';
这很简单,可能会有一些改进,但你明白了。

通过
触发对象并对照已知类型的映射检查结果,避免了你提到的
RegExp
问题。从中,以下是地图:

// 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源代码可以学到很多东西


    • 正则表达式是一个函数

      /bar/(“bar”)=[“bar”]

      所以
      typeof/bar/=“function”


      尽管只有chrome认识到regexp文本可以用作函数。这一点是否应该如此有待商榷。你可以像对待函数一样对待它

      根据ECMAScript规范,以下内容应适用于:

      正则表达式文字是一个输入元素,在扫描时转换为RegExp对象()。对象是在包含程序或函数的计算开始之前创建的

      所以
      typeof/regex/
      应该产生
      “object”

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

      与此类似,a应生成函数对象:

      但是,尽管这返回一个函数对象,但不应产生
      “对象”
      ,而应产生
      “函数”

      typeof function(){} === "function"
      
      这是由于对象是否实现了特定于的



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

      变量的类型==='function'
      好!!变量。调用
      ,因为如果变量未定义或为空,
      !!variable.call
      会抛出错误。

      我相信你的解决方案更好。嗯,你想说
      typeof/regex/=='function'
      产生true吗?@Gumbo在chrome中是这样的。这太荒谬了。为什么不
      function(){}instanceof function
      ?@Worm问候:我刚刚在Chrome中尝试在函数上使用instanceof。得到“UncaughtTypeError:在instanceof check中需要一个函数,但得到了函数foo(){}”Um…?在Chrome10中,它的计算结果为true。这很有趣。“我不知道你能做那件事。”“帕特里克德,你是说该死的,真让人困惑!我知道必须开始将RegExp文本看作函数而不是对象。这只是一个专有的扩展。在ECMAScript中,正则表达式是对象。除非重新定义内部的
      对象.prototype.toString
      函数,否则正则表达式就是对象你能看看这个问题吗?@Gumbo:我错过了你之前的评论。说得好。我们不能在javascript中有一点确定性吗?!此解决方案不适用于IE8及以下版本。因为这些浏览器将内置函数视为对象。请检查:非常难闻且严格键入,-1以建议从中学习(顺便说一句,猴子式数组初始值设定项比常规的不吉利文字慢6-8倍)@Worm-感谢对-1的解释。我不认为这里的性能问题值得担心,我认为这里还有一些东西需要学习,即使您决定不使用它。但是,感谢您花时间解释。您会注意到,被接受的、得票最多的答案使用了我所描述的jQuery方法的一个不太通用的版本。当然,最好的答案也练习“字符串类型化”。无论如何,模式与布尔.toString()相同。长度==4
在整个宇宙历史中,除了少数情况外,其他所有情况下,这里讨论的性能问题都无关紧要
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";
},
typeof /regex/ === "object"
/regex/.constructor === RegExp
(function(){}).constructor === Function
typeof function(){} === "function"