underscore.js中如何判断两个对象的内容相同 - WEB_YH的博客 - CSDN博客

    在js中,我们知道对象是引用类型,我们使用时定义的变量都是指向其内存地址。一个内存地址只对应一个对象,
内存地址不一样,两个对象就是内容再相同也是不相等的。
    有时候我们指的两个对象相等指的是内容相同,那么此时我们应该如何去比较两个对象内容相同呢,underscore.js
给出了两个主要函数:eq和deepEq函数。
    eq主要是进行基本的判断,比如+0和-0,NaN和NaN    deepEq主要对不同的基本类型进行判,(不同的基本类型对应不同的判断方法),其中数组是一个比较麻烦的对象,
如要比较数组里面的内容是否相同。
下面是两个函数的具体代码和注释
var eq,deepEq;    //eq是第一层比较,主要进行简单的筛别    eq = function(a,b,aStack,bStack){        if(a === b){            //0这个情况要特殊对待,因为我们认为+0不等于-0            return a !==0 || 1/a === 1/b;        }        if(a === null || b === null){            return false;        }        //用来判断NaN的情况        if(a !== a){            return b!==b;        }        var type = typeof a;        if(type !== 'function' && type !== 'object' && typeof b != 'object'){            return false;        }        //开始深度递归        return deepEq(a,b,aStack,bStack);    };    deepEq = function(a,b,aStack,bStack){        //如果a,b是_的一个实例        if(a instanceof _){            a = a._wrapped;        }        if(b instanceof _){            b = b._wrapped;        }        //通过对象所属的类进行第一步比较,类不相同直接pass掉        var className = toString.call(a);        if(className !== toString.call(b)){            return false;        }        //Strings, numbers, regular RegExp, dates, and booleans可以直接通过值来比较        switch(className){            case '[object RegExp]' :            case '[object String]' :                //字符串和正则可以看作是同一类,转化成字符串直接比较                return '' + a === '' + b;            case '[object Number]' :                if(+a !== +a){//判断NaN                    return  +b !== +b;                }                //正负0特别判断                return +a === 0 ? 1 / +a === 1 / b : +a === +b;            case '[object Date]' :            case '[object Boolean]' :                //Date和Boolean可以看作一类比较                return +a === +b;            case '[object Symbol]' :                return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);        }        //数组情况        var areArrays = className === '[object Array]';        if(!areArrays){//不是数组情况            if(typeof a != 'object' || typeof b != 'object'){//a,b有一个不是对象                return false;            }            //此时得到的a,b都是对象            var aCtor = a.constructor,bCtor = b.constructor;//得到a,b两个的构造函数            if(aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && _.isFunction(bCtor) &&                bCtor instanceof bCtor) && ('constructor' in a && 'constructor' in b)){                return false;            }        }        aStack = aStack || [];        bStack = bStack || [];        var length = aStack.length;        while(length--){            if(aStack[length] === a){                return bStack[length] === b;            }        }        //将a,b两个对象入栈        aStack.push(a);        bStack.push(b);        if(areArrays){//数组情况            length = a.length;//获取数组a的长度            if(length !== b.length){//长度不一致pass掉                return false;            }            while(length--){                if(!eq(a[length],b[length],aStack,bStack)){//判断数组内容是否相同                    return false;                }            }        }else{            //不是数组是对象的情况            var keys = _.keys(a),key; //得到a的所有键            length = keys.length;            if(_.keys(b).length !== length){//如果a,b的键数组的长度不一致,pass掉。                return false;            }            //a,b的键数组长度一致            while(length--){                key = keys[length];//从键数组中获取键                if(!(_.has(b,key) && eq(a[key],b[key],aStack,bStack))){                    //b里面没有该键名pass掉, &&后的这个条件用来判断键值是否相等,(键值也可能是对象什么的)                    return false;                }            }        }        //出栈操作        aStack.pop();        bStack.pop();        return true;    };    _.isEqual = function(a,b){        return eq(a,b);    };

Original url: Access
Created at: 2019-11-26 22:19:56
Category: default
Tags: none

请先后发表评论
  • 最新评论
  • 总共0条评论