• JS框架设计之对象类型判断一种子模块


    Javascript有两套数据类型,一套是基础数据类型,一套是对象数据类型。基础数据类型包括5种基本数据类型,分别是null,bool,undefined,number,string,也叫简单数据类型,object是复杂数据类型,其中Object,Array,Function属于引用类型(对象数据类型)。

    基于这么多数据类型,所以JS就自带有类型判定的方法,typeof  用来检测基本数据类型,instanceof 用来检测对象数据类型,但是JS自带的这两套识别机制并不靠谱,所以产生了isXXX一系列来判断数据类型的方法,就拿typeof来说,他只能粗略的识别出string、number、boolean、function、undefined、object这6中数据类型,无法识别Null,RegExpAragument等细分对象类型

         /*
         Javascript有两套数据类型,一套是基础数据类型,一套是对象数据类型。基础数据类型包括5种基本数据类型,分别是null,bool,undefined,number,string,也叫简单数据类型,
         object是复杂数据类型,其中Object,Array,Function属于引用类型(对象数据类型)。基于这么多数据类型,所以JS就自带有类型判定的方法,typeof  用来检测基本数据类型,
         instanceof 用来检测对象数据类型,但是JS自带的这两套识别机制并不靠谱,所以产生了isXXX一系列来判断数据类型的方法,就拿typeof来说,
         他只能粗略的识别出string、number、boolean、function、undefined、object这6中数据类型,无法识别Null,RegExpAragument等细分对象类型
         */
        //下面就是自带的Js识别系统所带的坑
    
        console.log(typeof null);//输出:object
        console.log(typeof document.childNodes);//safari 输出:function
        console.log(document.createElement("embed"));//ff3-10  输出:function,其他浏览器都输出object
        console.log(document.createElement("object"));//ff3-10  输出:function,其他浏览器都输出object
        console.log(document.createElement("applet"));//ff3-10  输出:function,其他浏览器都输出object
        console.log(typeof /d/i);//在实现了ecma262v4的浏览器上输出:function
        console.log(typeof window.alert);//IE678  输出:object, 其他浏览器输出:function
        //以上就是typeof的坑
    
    
    
        var iframe=document.createElement("iframe");
        document.body.appendChild(iframe);
        xArray=window.frames[window.frames.length-1].Array;
        var arr=new xArray(1,2,3);
        console.log(arr);//输出:1,2,3
        console.log(arr instanceof Array);//输出:false
        console.log(arr.constructor===Array);//输出:false
        //以上是instnceof的坑,只要原型上存在此对象的构造函数,那么就返回true,但是如果跨文档比较,iframe里面的数组实例就不是父窗口里面的Array的实例
    
        window.onload=function () {
            console.log(window.constructor);//IE67 undefined 其他object
            console.log(document.constructor);//IE67 undefined 其他object
            console.log(document.body.constructor);//IE67 undefined 其他object
            console.log((new ActiveXObject("Microsoft.XMLHttp")).constructor);//IE6789 undefined
        }
        //以上是constructor的坑,产生以上问题的原因是在旧版本IE下DOM和BOM是没有暴露出来的
    
         console.log(isNaN("aaa"));//输出:true
         console.log(isNaN(new Object()));//输出:true
        //isNaN这个方法非常不靠谱,当我们传入字符串和对象时,输出也是true,这对我们的序列化是非常不利的
    
    
        if(typeof window.ActiveXObject!="undefined")
        {
            var  xhr=new ActiveXObject("Msxml2.XMLHTTP");
            console.log(typeof xhr.abort);//输出:unknown
        }
        //以上是在IE下的typeof返回unknown的情况
    
        /*
        之前大多数人用document.all是否存在来判定IE,因为用document.all来取得页面中的元素是不错的注意,但是这个方法其他浏览器也觊觎了好久,
        于是就有了Chrome下的闹剧
         */
        console.log(typeof document.all); //IE78中输出:object,在Chrome中输出:undefined
        console.log(document.all);//在Chrome中,虽然typeof输出的是:undefined,但是document.all却能获取到所有的网页元素,输出:HTMLAllCollection[6]
       /*
        以下是jQuery判断js数据类型的方法$.type
         */
        var jQuery={};
        var class2Type={};
        var dataType=["Boolean","Number","String","Function","Array","Date","RegExpObject","Function"];
        for(var i=0;i<dataType.length;i++)
        {
            class2Type["[object "+dataType[i]+"]"]=dataType[i].toLowerCase();
        }
        jQuery.type=function (obj) {
            return obj==null?obj+"":class2Type[Object.prototype.toString.call(obj)] || "object";
        }
    
        var aa=false;
        function bb(){}
        alert(Object.prototype.toString.call(aa))//输出:[object Number]
        alert(jQuery.type(bb))//输出:number
        var mass={};
        var class2Type={
            "[objectHTMLDocument]":"Document",
            "[objectHTMLCollection]":"NodeList",
            "[objectStaticNodeList]":"NodeList",
            "[obejctIXMLDOMNodeList]":"NodeList",
            "[objectDOMWindow]":"Window",
            "null":"Null",
            "NaN":"NaN",
            "undefined":"Undefined"
        }
        var toString=class2Type.toString;
        var AllDataType=["Boolean","Number","String","Function","Array","Date","RegExp","Error","Symbol","Arguements","Window","Document"];
        //填充class2Type集合用于判断js数据类型,通过Object.prototype.toString.call()来判断解决typeof和instanceof"不靠谱"的问题
        //class2Type这个映射几乎将所有的对象类型一网打尽
        for(var i=0;i<AllDataType.length;i++)
        {
            class2Type["[object "+AllDataType[i]+"]"]=AllDataType[i];
        }
        mass.type=function (obj,str) {
            //1、当传入的对象不等于null或者自己的类型不等于自己的时候,直接去class2Type中找自己的类型,
            // 2、如果找不到做Object.prototype.toString转换,再去class2type中找
            //3、如果在class2type中找不到类型,那么找传入对象的nodeName(传入的参数可能是html元素节点)
            //4、如果上面的条件都不满足那么就把result设为"#"
            var result=class2Type[(obj==null || obj!==obj?obj:toString.call(obj))] || obj.nodeName || "#";
            //兼容旧版本浏览器处理个别情况,如window,opera
            //利用IE678中window==document为true,document==window为false的神奇特性
            if(result.charAt(0)=="#")
            {
                if(obj==obj.document && obj.document!=obj)
                {
                    result="Window";
                }
                else if(obj.nodeType===9)
                {
                    result="Document";
                }
                else if(obj.callee)
                {
                    result="Arguements";
                }
                else if(isFinite(obj.length) && obj.item)
                {
                    result="NodeList";
                }else
                {
                    result=toString.call(obj).slice(8,-1);
                }
            }
            if(str)
            {
                return str===result;
            }
            return result;
        }
        //type方法直接用toString.call(obj)做键,直接从事先存好的映射中取出。只有在IE6、IE7、IE8中才废一些周折处理window、document
        //Arguement、nodeList等模块
  • 相关阅读:
    谷歌浏览器默认字体最小12px的解决方案
    字符编码笔记:ASCII,Unicode和UTF8 (转)
    关于URL编码(转)
    .net 应用程序域的影子复制
    .net动态加载程序集和影子复制(Dynamic Load Assembly and Shadow Copy)
    关于.net影子复制的问题
    来得有点晚,不过博客不分先后 :)
    App Domains and dynamic loading
    AppDomain and Shadow Copy
    Delphi实现软件自动更新源代码
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/6410854.html
Copyright © 2020-2023  润新知