• javascript之判断专题


    javascript有数组,对象,函数,字符串,布尔,还有Symbol,set,map,weakset,weakmap。

    判断这些东西也是有很多坑,像原生的typeof,instanceOf有一些bug,有些能满足90%的情况,也有些不太如人意。

    所以各大类库都出了一些判断的函数,以is开头的xxx。

    1,判断null
    typeof null//'object',所以不能用typeof判断。typeof的一个坑。

    null大家都是用 null===null判断的。jquery阿underscore都是这么写:

    function isNull(obj){return obj===null}

    2.undefined

    typeof undefined==="undefined",还不能直接写undefined,而jq等类库和underscore都是这么写的:

    function isUndefined(obj){return obj===void 0;}

    3.NaN

    typeof NaN==="number",js内置的isNaN在输入字符串,对象都返回true,白瞎这个名字了,不过倒是有人用这个判断数字,!isNaN(number)。所以判断NaN的时候是:

    function isNaN(obj){return obj!==obj}

    jquery,underscore等类库也都是这么判断,看来大家意见差不多。

    3.window对象

    jquery的判断window对象

    //判断window
    function isWindow(){
        window==document//IE678 true
        document==window//IE678 false
    }

    3.判断基础类型Numberbooleanfunctionstring

    //typeof判断string,number,boolean,function可满足90%的需求
    //但是。。。
    typeof new Boolean(1);//"object"
    typeof new Number(1);//"object"
    typeof new String(1);//"object"

    这些要判断也蛮简单的,上一下underscore的源码吧。

    _.isFunction / _.isString / _.isNumber / _.isDate / _.isRegExp都是这样。。用Object.prototype.toString.call(obj)判断

    刚刚试了下,Object.toString.call和原型链上的toString返回的不一样-0-。

    _.isFunction = function(obj) {
        return Object.protorype.toString.call(obj) == '[object Function]';
    };

    underscore的boolean的判断还是蛮全的,包括字面量,对象形式的boolean:

    _.isBoolean = function(obj) {
        return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
    };

    4.object

    typeof 太多东西都是object了,看看underscore咋判断

    _.isObject = function(obj) {
        return obj === Object(obj);
    };
    //这里
    typeof null//'object'
    typeof []//object
    typeof /d/i //"object"
    typeof window.alert //IE678 "object"

     5.element

    _.isElement = function(obj) {
        return !!(obj && obj.nodeType == 1);
    };

    6.Arguments

    这是underscore的判断Arguments,和源码,注释很清楚也不多说。

    _.isArguments = function(obj) {
        return toString.call(obj) == '[object Arguments]';
    };
    // 验证isArguments函数, 如果运行环境无法正常验证arguments类型的数据, 则重新定义isArguments方法
    if(!_.isArguments(arguments)) {
        // 对于环境无法通过toString验证arguments类型的, 则通过调用arguments独有的callee方法来进行验证
        _.isArguments = function(obj) {
            // callee是arguments的一个属性, 指向对arguments所属函数自身的引用
            return !!(obj && _.has(obj, 'callee'));
        };
    }

    7.Array

    判断数组是最麻烦的,前面的还好,数组默认的0,1,2,3的下标,一个length属性,一些Array方法,判断的时候还要保证obj不是类数组,还要保证不是Arguments。。

    我们看一下这些类库探索Array的路程

    开始是

    return arr.instanceof Array;

    后来

    return !!arr&&arr.constructor==Array;
    return typeof arr.sort=='function'
    return try{
        Array.prototype.toString.call(o);
        return true;
    }catch(e){
        return false;
    }

    从instanceof判断,constructor的判断到Array的toString方法的判断,可谓是用尽心思,最新版的jquery的判断array好像把这好多方法集合在一起,写的老长。

    underscore的判断还是用它的toString.call判断:

    _.isArray = nativeIsArray ||
    function(obj) {
        return toString.call(obj) == '[object Array]';
    };

    如果js原生支持isArray就先用原生的,这个nativeIsArray在一开始被设置为Array的isArray方法。

    各大框架也有类数组的判断,这个更麻烦,老长的代码,判断原理是类数组的length属性能被重写,而数组的length属性不能被重新,代码就不贴了。

     8.iframe

    //判断页面是否在iframe
    function(){
        alert(window!=window.top)
        alert(window.frameElement!==null)
        alert(window.eval!==top.eval)
    }
    //判断iframe与父页面同源
    function isSameOrigin(el){
        var ret=false;
        try{
            ret=!!el.contentWindow.location.href;
    
        }catch(e){}
        return ret;
    }

    附赠取iframe的函数

    //取iframe的对象
    function getIframeDocument(node){
        return node.contentDocument||node.contentWindow.document
    }

    总结一下原生判断的一些坑。

    //typeof 的陷阱
    typeof null//'object'
    typeof []//object
    typeof document.childNodes //safari "function"
    typeof document.createElement('embed')//ff3-10 "function"
    typeof document.createElement('object')//ff3-10 "function"
    typeof document.createElement('applet')//ff3-10 "function"
    typeof /d/i
    typeof window.alert //IE678 "object"
    //instanceof不能跨文档比较 iframe里面的数组实例不是父窗口的Array实例
    instanceof
    //contructor的陷阱 
    //旧版本ie下dom bom对象的constructor属性没有暴露出来

    好,今天就写这么多,谢谢观看,如有错误,请指出,大家共同学习~

      

  • 相关阅读:
    linux下使用tar命令
    ContentType和@ResponseBody
    ActiveMQ两种模式PTP和PUB/SUB<转>
    Postgresql分表与优化
    PostgreSQL存储过程<转>
    PostgreSQL Table Partitioning<转>
    Postgresql查询表的大小
    Postgresql添加/删除触发器示例
    Android TextView 支持的HTML标签
    我只是一直很努力
  • 原文地址:https://www.cnblogs.com/dh-dh/p/5077239.html
Copyright © 2020-2023  润新知