zoukankan      html  css  js  c++  java
  • 看jquery3.3.1学js类型判断的技巧

    需要预习:call , typeof, js数据类型

    1. isFunction中typeof的不靠谱

    源码:

    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 是为了区分数据类型,下面是MDN中总结的typeof中所有存在的值

    问题一:我们都知道typeof null 出来的结果是‘object’,可这是为啥呢?MDN给出了答案 :因为null是空指针,而空指针在大多数平台中使用0x00表示,而js在实现初期通过用 0 作为对象的标签,所以对null也被判断为object。

    问题二:既然typeof能够判断出function,为何jquery额外判断   typeof obj.nodeType !== "number" 呢?

                long long ago,在那些古老的浏览器中:

                1. typeof document.body.childNodes  // function   这在古老的 safari 3 中会出现

                2.typeof document.createElement("object")  // function 同理还有 'embed'  'applet' ,  在古老的firefox中会出现,目前新版本不会存在

                3.typeof /s/ // function  这种情况会在古老浏览器中出现,目前都会被判定为 object

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

    2.靠谱的数据类型判断 

    源码:

    var class2type = {};
    
    var toString = class2type.toString;
    
    // Populate the class2type map,这里并没有undefined
    jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
    function( i, name ) {
        class2type[ "[object " + name + "]" ] = name.toLowerCase();
    } );
    
    function toType( obj ) {
        if ( obj == null ) {
            return obj + "";
        }
    
        // Support: Android <=2.3 only (functionish RegExp)
        return typeof obj === "object" || typeof obj === "function" ?
            class2type[ toString.call( obj ) ] || "object" :
            typeof obj;
    }

    在代码中jquery做了这几件事:

    1.jquery先提取出toString 这个方法

    2.将写好的类型字符串分割并存入class2type中,class2type 数据结构如下:

    3.定义toType方法,因为 toString(null)会得出‘ [object Undefined]’的结果,所以需要把null单独判断,注意null是没有toString这个方法的,所以通过 obj+''这个方式得到 'null'

    4.在单独判断null后是一个三元运算符:等价于

    1 if(typeof obj === "object" || typeof obj === "function"){
    2     // 因为上文提到存在typeof /s/ 为 function的情况,所以需要toString详细判断
    3    // 对于判断不出的数据类型默认为object
    4     retrun class2type[ toString.call( obj ) ] || "object";
    5 } else {
    6     // 通过上面typeof对类型判断的表格,判断非object function还是很可靠的,所以直接用原生方法
    7     return typeof obj;
    8 }

    结论: 通过用toString方法可以判断出Boolean、Number、 String、 Function、 Array、 Date、 RegExp、 Object、 Error、 Symbol、undefined 这些数据类型,但是并不能判断出null,所以要综合判断,就酱

    除此之外jquery还额外判断了当前对象是否为window,只用了如下的方法:

    var isWindow = function isWindow( obj ) {
            return obj != null && obj === obj.window;
        };

    前方的obj!=null 是为了防止开发人员在调用函数 isWindow时传入null 、undefined的时候报Uncaught TypeError: Cannot read property 'window' of null/undefined的错误。

    还有isArrayLike,判断当前对象是不是类数组对象,类数组对象是什么,建议大家百度一下

    function isArrayLike( obj ) {
    
        // Support: real iOS 8.2 only (not reproducible in simulator)
        // `in` check used to prevent JIT error (gh-2145)
        // hasOwn isn't used here due to false negatives
        // regarding Nodelist length in IE
        var length = !!obj && "length" in obj && obj.length,
            type = toType( obj );
    
        if ( isFunction( obj ) || isWindow( obj ) ) {
            return false;
        }
    
        return type === "array" || length === 0 ||
            typeof length === "number" && length > 0 && ( length - 1 ) in obj;
    }

    首先判断obj中是否有length属性并取出length

    然后排除obj是否是window 及 function

    最后取值条件:1.是否是array(类数组对象集合当然包括数组) 2.存在length属性但length是0  3.判定length是数字且大于零,并在obj对象中存在length-1属性

  • 相关阅读:
    [AWS] Lab
    [AWS] Lab
    [AWS] Launch the VPC Wizard
    [AWS] EC2 Dashboard
    mysql .net下载
    币乎咕噜DeFi踩雷记
    量化分析师关于有限差分方法(FDM)最好的5本书
    QuantStart量化交易文集
    Exploring Market Making Strategy for High Frequency Trading: An Agent-Based Approach
    什么是信息比率?信息比率与夏普比率的差别?
  • 原文地址:https://www.cnblogs.com/JhoneLee/p/8856567.html
Copyright © 2011-2022 走看看