美文网首页
jQuery 类型判断 源码解读

jQuery 类型判断 源码解读

作者: Kevin丶CK | 来源:发表于2019-08-22 16:42 被阅读0次

    准备工作

    typeof

    typeof操作符返回一个字符串,表示未经计算的操作数的类型。
    下表总结了typeof可能的返回值。有关类型和原始值的更多信息,可查看 JavaScript数据结构 页面。

    类型 结果
    Undefined "undefined"
    Null "object"(见下文)
    Boolean "boolean"
    Number "number"
    String "string"
    Symbol (ECMAScript 6 新增) "symbol"
    宿主对象(由JS环境提供) Implementation-dependent
    函数对象([[Call]] 在ECMA-262条款中实现了) "function"
    任何其他对象 "object"

    call

    call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

            let obj ={};
            console.log(obj.toString());//[object Object]
            console.log(obj.toString.call(new String));//[object String]
            console.log(obj.toString.call(new Date));//[object Date]
            console.log(obj.toString.call(new Array));//[object Array]
            console.log(obj.toString.call(new Number));//[object Number]
            console.log(obj.toString.call(Function));//[object Function]
            console.log(obj.toString.call(Math));//[object Math]
            console.log(obj.toString.call(undefined));//[object Undefined]
            console.log(obj.toString.call(null));//[object Null]
    

    null

    最特殊的null,下面是MDN的解释:
    在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null的类型标签也成为了 0,typeof null就错误的返回了"object"。(曾经看过某易的大神说就是这么设计的,不是故意错误返回object,null不是基础类型,因为typeof null === 'object'

    源码解析

    本文中,jQuery才用的是3.4.1版本。一般情况下判断数据类型,采用typeof即可,为啥JQuery还进行了自己的封装呢,很说明存在漏洞。我们先从jQuery判断对象入手。

    var isFunction = function isFunction( obj ) {
    
          // Support: Chrome <=57, Firefox <=52
          // In some browsers, typeof returns "function" for HTML <object> elements
          // (i.e., `typeof document.createElement( "object" ) === "function"`).
          // We don't want to classify *any* DOM node as a function.
          return typeof obj === "function" && typeof obj.nodeType !== "number";
      };
    

    结合上面的typeof的知识,已经能判断出function,为什么还 多余 的判断typeof obj.nodeType !== "number"。注释已经给出答案,在某些古老的浏览器中,typeof document.body.childNodes // function
    还有MDN上也指出,对正则表达式字面量的类型判断在某些浏览器中不符合标准

    typeof /s/ === 'function'; // Chrome 1-12 , 不符合 ECMAScript 5.1
    typeof /s/ === 'object'; // Firefox 5+ , 符合 ECMAScript 5.1
    

    所以通过typeof判断数据类型在古老的浏览器中是极为不靠谱的,所以在jquery的isFunction的判断中额外添加了判断 检测对象是否为dom对象。

    jQuery 判断类型

    有了上面的基础typeofcall,再看下面源码,结合注释基本就什么阻碍了。

    var class2type = {};//定义一个空对象
    var toString = class2type.toString;
    function toType( obj ) {
        if ( obj == null ) {//null 特殊处理
            return obj + "";
        }
    
           // Support: Android <=2.3 only (functionish RegExp)
           //一个三元运算符
          // 因为上文提到存在typeof /s/ 为 function的情况,所以需要toString详细判断
         //对于判断不出的数据类型默认为object
         // 通过上面typeof对类型判断的表格,判断非object function还是很可靠的,所以直接用原生方法
        return typeof obj === "object" || typeof obj === "function" ?
            class2type[ toString.call( obj ) ] || "object" :
            typeof obj;
    }
    // Populate the class2type map
    //把所以类型的字符串分割成字符串数组,遍历后以[object object]为key保存在class2type对象中(如下图)
    jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
    function( i, name ) {
        class2type[ "[object " + name + "]" ] = name.toLowerCase();
    } );
    
    class2type

    总结

    通过用toString方法可以判断出Boolean、Number、 String、 Function、 Array、 Date、 RegExp、 Object、 Error、 Symbol、undefined 这些数据类型。并不能判断出null,所以要采用上面的方式。

    相关文章

      网友评论

          本文标题:jQuery 类型判断 源码解读

          本文链接:https://www.haomeiwen.com/subject/tmvnsctx.html