zoukankan      html  css  js  c++  java
  • js中判断Object、Array、Function等引用类型对象是否相等的方法

     js中判断Object、Array、Function等引用类型对象是否相等,引用类型无法直接使用 == 或=== 取得期待结果。
    法一:需要一个迭代的compare函数转化成原始类型进行比较
    function compare(a,b){ 
    var pt = /undefined|number|string|boolean/, fn = /^(function\s*)(\w*\b)/, cr = "constructor", cn = "childNodes",
     pn ="parentNode", 
    ce = arguments.callee; 
    if(pt.test(typeof a) || pt.test(typeof b) || a === null || b === null){ 
        return a === b || (isNaN(a) && isNaN(b)); //为了方便,此处假定NaN == NaN 
    } 
    if(a[cr] !== b[cr]){ 
        return false; 
    } 
    switch(a[cr]){ 
        case Date : { 
            return a.valueOf() === b.valueOf(); 
        }; 
        case Function : { 
            return a.toString().replace(fn,'$1') === b.toString().replace(fn,'$1'); //硬编码中声明函数的方式会影响到toString的结果,因此用正则进行格式化 
        }; 
        case Array : { 
            if(a.length !== b.length){ 
                return false; 
            } 
            for(var i=0;i<a.length;i++){ 
                if(!ce(a[i],b[i])){ 
                    return false; 
                } 
            } 
        break; 
        }; 
        default : { 
            var alen = 0, blen = 0, d; 
            if(a === b){ 
                return true; 
            } 
            if(a[cn] || a[pn] || b[cn] || b[pn]){ 
                return a === b; 
            } 
            for(d in a){ 
                alen++ ; 
            } 
            for(d in b){ 
                blen++; 
            } 
            if(alen !== blen){ 
                return false; 
            } 
            for(d in a){ 
                if(!ce(a[d],b[d])){ 
                    return false; 
                } 
            } 
            break; 
        }; 
    } 
        return true; 
    } 
    console.log(compare({},{a:1})); //false 
    console.log(compare({a:1},{b:2})); //false 
    console.log(compare({b:2,a:1},{a:1,b:2})); //true 
    console.log(compare({a:function(){return false;},b:2},{a:function(){return false;},b:2})); //true 
    console.log(compare([],[])); //true 
    console.log(compare([2,1],[1,2])); //false 
    console.log(compare(function(){alert(1)},function(){})); //false 
    console.log(compare(function aaa(){alert(1)},function(){alert(1)})); //true 
    console.log(compare(document.getElementsByTagName("a")[0],document.getElementsByTagName("a")[1])); //true 
    console.log(compare(document.getElementsByTagName("a")[0],document.getElementsByTagName("a")[0])); //true 

    法二:直接检测Array或Object的  用arguments.callee
    function equal(objA, objB)
    {
        if (typeof arguments[0] != typeof arguments[1])
            return false;
        console.log(arguments[0],arguments[1]);
        //数组
        if (arguments[0] instanceof Array)
        {
            if (arguments[0].length != arguments[1].length)
                return false;
            
            var allElementsEqual = true;
            for (var i = 0; i < arguments[0].length; ++i)
            {
                if (typeof arguments[0][i] != typeof arguments[1][i])
                    return false;
    
                if (typeof arguments[0][i] == 'number' && typeof arguments[1][i] == 'number')
                    allElementsEqual = (arguments[0][i] == arguments[1][i]);
                else
                    allElementsEqual = arguments.callee(arguments[0][i], arguments[1][i]);            //递归判断对象是否相等                
            }
            return allElementsEqual;
        }
        
        //对象
        if (arguments[0] instanceof Object && arguments[1] instanceof Object)
        {
            var result = true;
            var attributeLengthA = 0, attributeLengthB = 0;
            for (var o in arguments[0])
            {
                //判断两个对象的同名属性是否相同(数字或字符串)
                if (typeof arguments[0][o] == 'number' || typeof arguments[0][o] == 'string')
                    result = eval("arguments[0]['" + o + "'] == arguments[1]['" + o + "']");
                else {
                    //如果对象的属性也是对象,则递归判断两个对象的同名属性
                    //if (!arguments.callee(arguments[0][o], arguments[1][o]))
                    if (!arguments.callee(eval("arguments[0]['" + o + "']"), eval("arguments[1]['" + o + "']")))
                    {
                        result = false;
                        return result;
                    }
                }
                ++attributeLengthA;
            }
            
            for (var o in arguments[1]) {
                ++attributeLengthB;
            }
            
            //如果两个对象的属性数目不等,则两个对象也不等
            if (attributeLengthA != attributeLengthB)
                result = false;
            return result;
        }
        return arguments[0] == arguments[1];
    
    }
    
    var a = {Name:"YuanXP",Id:9,Go:{a:'1',b:'2'}};
    var b = {Id:9,Name:"YuanXP",'Go':{a:'1',b:'2'}};
    
    var c= equal(a, b);
    console.log(c); 
  • 相关阅读:
    Zend Framework 2.1.5 中根据服务器的环境配置调用数据库等的不同配置
    在基于 Eclipse 的 IDE 中安装和使用 Emmet(ZenCoding)
    【翻译】Emmet(Zen Coding)官方文档 之六 自定义 Emmet
    【翻译】Emmet(Zen Coding)官方文档 之二 缩写
    【翻译】Emmet(Zen Coding)官方文档 之七 一览表
    【翻译】Emmet(Zen Coding)官方文档 之三 CSS 缩写
    【翻译】Emmet(Zen Coding)官方文档 之四 动作
    【翻译】Emmet(Zen Coding)官方文档 之一 web 编程的必备工具
    Zend Framework 2 时区设置警告问题的解决
    【翻译】Emmet (Zen Coding) 元素类型
  • 原文地址:https://www.cnblogs.com/onflying/p/2989330.html
Copyright © 2011-2022 走看看