zoukankan      html  css  js  c++  java
  • 类数组和类型判定

    数组化

    数组是一个很好的存储结构,不过光像以下这样声明类数组功能略弱:

    var arrayLike = {
             0: 'a',
             1: 'b',
             2: 'c',
             length: 3
    }

    为了使其拥有数组的功能,通常会将其进行数组化转化,一般的,我们只要使用[].slice.call就可以完成了。但是在IE中,HTMLCollection、NodeList并不是Object的子类,前面这个方法会导致IE报错,来看下几个经典的处理方法:

    // jQuery makeArray
    makeArray: function( arr, results ) {
        var ret = results || [];
    
        if ( arr != null ) {
            if ( isArraylike( Object(arr) ) ) {
                jQuery.merge( ret,
                    typeof arr === "string" ?
                    [ arr ] : arr
                );
            } else {
                push.call( ret, arr );
            }
        }
    
        return ret;
    },
    
    // 其中调用的merge
    merge: function( first, second ) {
        var len = +second.length,
            j = 0,
            i = first.length;
    
        while ( j < len ) {
            first[ i++ ] = second[ j++ ];
        }
    
        // Support: IE<9
        // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
        if ( len !== len ) {
            while ( second[j] !== undefined ) {
                first[ i++ ] = second[ j++ ];
            }
        }
    
        first.length = i;
    
        return first;
    }

    Ext的toArray:

    toArray : function(){   
    
     return isIE ?   
    
         function(a, i, j, res){   
    
             res = [];   
    
             for(var x = 0, len = a.length; x < len; x++) {   
    
                 res.push(a[x]);   
    
             }   
    
             return res.slice(i || 0, j || res.length);   
    
         } :   
    
         function(a, i, j){   
    
             return Array.prototype.slice.call(a, i || 0, j || a.length);   
    
         }   
    
    }(),

    Ext的方式很巧妙,它是立刻执行自身,对于不同环境返回不同的toArray函数。这样使得在后期可以直接调用,而不必再次判断浏览器的类型。

    在mass中的实现方法也是一开始就区分出来:

    slice: W3C ? function(nodes, start, end) {
        return factorys.slice.call(nodes, start, end);
    } : function(nodes, start, end) {
        var ret = [],
                n = nodes.length;
        if (end === void 0 || typeof end === "number" && isFinite(end)) {
            start = parseInt(start, 10) || 0;
            end = end == void 0 ? n : parseInt(end, 10);
            if (start < 0) {
                start += n;
            }
            if (end > n) {
                end = n;
            }
            if (end < 0) {
                end += n;
            }
            for (var i = start; i < end; ++i) {
                ret[i - start] = nodes[i];
            }
        }
        return ret;
    }

    类型的判定

    在Javascript中,类型的判定分为基本类型的判定和对象类型系统的判定,分别用typeof和instanceof,不过在其中有数不清的陷阱,先列几个:

    typeof null // 'object'
    typeof document.childNodes  //safari 'function'
    typeof document.createElement('embed')  //ff3-10 'function'
    
    isNaN('aaa')  //true
    
    window.onload = function(){
        alert(window.constructor);  // IE 67  undefined
        alert(document.constructor);  //IE 67 undefined
    }

     想看完整版的可以到司徒正美大大的书《Javascript框架设计》里找哇~

    这些奇奇怪怪的bug使得我们在判定时会出现这样那样的问题,对于undefined,null,string,number,boolean,function这6个比较简单,前两个可以和void(0),null比较,后面的用typeof也可以满足大部分的情况。

    但是对于Array来说,这就比较困难了。由于Javascript中的鸭子类型被攻破,导致了isArray的编写困难。不过在最后prototype.js的Object.prototype.toString将对象内部的[[Class]]显现出来,使得Array判断极其精准。

    Javascript早期的几个isArray的探索:

    function isArray(o){
         return arr instanceof Array;
    }
    
    function isArray(o){
         try {
              Array.prototype.toString.call(o);
              return true;
         } catch(e) {}
         return false;
    }

    这样几个类型的判断都有了

    对于null,undefined,NaN,下面这样就可以了:

    function isNaN(obj){
         return obj !== obj;
    }
    
    function isNull(obj){
         return obj === null;
    }
    
    function isUndefined(obj){
         return obj === void 0;
    }

    在jQuery中,用type代替了关键字typeof:

    type: function( obj ) {
        if ( obj == null ) {
            return obj + "";
        }
        return typeof obj === "object" || typeof obj === "function" ?
            class2type[ toString.call(obj) ] || "object" :
            typeof obj;
    }
    
    jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
        class2type[ "[object " + name + "]" ] = name.toLowerCase();
    });

    mass Framework 的思路与jQuery一致,尽量减少isXXX的数量:

    var class2type = {
            "[object HTMLDocument]": "Document",
            "[object HTMLCollection]": "NodeList",
            "[object StaticNodeList]": "NodeList",
            "[object DOMWindow]": "Window",
            "[object global]": "Window",
            "null": "Null",
            "NaN": "NaN",
            "undefined": "Undefined"
        };
    
    "Boolean,Number,String,Function,Array,Date,RegExp,Window,Document,Arguments,NodeList".replace($.rword, function(name) {
        class2type["[object " + name + "]"] = name;
    });
    
    type: function(obj, str) {
        var result = class2type[(obj == null || obj !== obj) ? obj : serialize.call(obj)] || obj.nodeName || "#";
        if (result.charAt(0) === "#") { //兼容旧式浏览器与处理个别情况,如window.opera
            //利用IE678 window == document为true,document == window竟然为false的神奇特性
            if (obj == obj.document && obj.document != obj) {
                result = "Window"; //返回构造器名字
            } else if (obj.nodeType === 9) {
                result = "Document"; //返回构造器名字
            } else if (obj.callee) {
                result = "Arguments"; //返回构造器名字
            } else if (isFinite(obj.length) && obj.item) {
                result = "NodeList"; //处理节点集合
            } else {
                result = serialize.call(obj).slice(8, -1);
            }
        }
        if (str) {
            return str === result;
        }
        return result;
    }

    差不多就到这了,这篇基本属于《Javascript框架设计》读书笔记吧,大家有兴趣可以去读读哦~

    匿了。。。。

  • 相关阅读:
    OpenWrt 上安装 AdGuard Home
    java网络编程
    如何进行数据库选型
    银行业务中台
    数仓|大数据时代,维度建模过时了吗?
    spqrk相关
    Apache Doris在美团外卖数仓中的应用实践
    hadoop的简单规划
    数据中台建设
    银行数仓分层
  • 原文地址:https://www.cnblogs.com/cyITtech/p/3730130.html
Copyright © 2011-2022 走看看