美文网首页工作生活
JavaScript 比较两个对象

JavaScript 比较两个对象

作者: Kevin丶CK | 来源:发表于2019-07-04 14:41 被阅读0次

背景

对象的比较使用=====比较,即使拥有相同的属性和相同的值,但很有可能不相等的。这是因为它们是通过它们的引用来比较的(也就是在内存中的地址)。所以就需要通过比较对象自身的属性。

分析

1.如果比较的两个对象===,返回true

        let obj = {
          id: 1213,
          name: "张三"
        };
        let obj2 =obj;
        console.log(obj === obj); //true
        console.log(obj === obj2); //true

2.如果比较的是两个方法,转成字符串比较
toString()和valueOf()又不太了解的可以阅读这篇文章

      let fun1 = function(param) {
        console.log(arguments);
      };
      let fun3 = function(param) {
        console.log(arguments);
      };
      console.log(fun1 == fun3); //false
      console.log(fun1.toString() == fun3.toString()); //true

3.如果比较的是两个是Date对象,直接获取毫秒值比较

    let mDate1 = new Date();
    let mDate2 = new Date();
    console.log(mDate1.getTime() === mDate2.getTime());//true

2.判断完上面的特殊情况,比较是两个 对象 类型不一致

    let obj1=123;
    let obj2='123';
    let obj3='abc';
    console.log(Object.prototype.toString.call(obj1));//[object Number]
    console.log(Object.prototype.toString.call(obj2));//[object String]
    console.log(Object.prototype.toString.call(obj1)===Object.prototype.toString.call(obj2));//false
    console.log(Object.prototype.toString.call(obj2)===Object.prototype.toString.call(obj3));//true

5.两个对象开始比较自身属性(包括长度)

      let obj1 = {
        id: 1213,
        name: "张三"
      };
      let obj2 = {
        id: 1213,
        name: "张三"
      };
      //获取对象所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)
      const obj1Props = Object.getOwnPropertyNames(obj1);
      const obj2Props = Object.getOwnPropertyNames(obj2);
      console.log(obj1Props.length === obj2Props.length );
      console.table(obj1Props);
      console.table(obj2Props);

这样就可以遍历属性的值是否相同。

总结

结合上面的几种情况,就可以写出一个判断对象是否相等的方法(相等指的是属性和属性值相等,不去深究其原型是否相等)

    function isDeepObjectEqual(obj1, obj2) {

        //1.如果是比较对象===,返回true
        if (obj1 === obj2) return true;
 
        //2.如果比较的是两个方法,转成字符串比较
        if (typeof obj1 === "function" && typeof obj2 === "function") return obj1.toString() === obj2.toString();

        //3如果obj1和obj2都是Date实例,获取毫秒值比较
        if (obj1 instanceof Date && obj2 instanceof Date) return obj1.getTime() === obj2.getTime();

         //4如果比较是两个类型不一致,无须比较直接返回false
         if ( Object.prototype.toString.call(obj1) !==Object.prototype.toString.call(obj2) || typeof obj1 !== "object") return false;
        
        //5.获取对象所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性
        const obj1Props = Object.getOwnPropertyNames(obj1);
        const obj2Props = Object.getOwnPropertyNames(obj2);

        //自身属性长度相等,
        if(obj1Props.length !== obj2Props.length) return false;

        //递归调用判断每一个属性值是否相等
        return (obj1Props.every(prop => isDeepObjectEqual(obj1[prop], obj2[prop])));
      }

下面测试一下(上面的判断顺序得注意了,由于要使用递归,还有就是判断一些他特殊对象,最好先判断特殊对象,在按照一般对象比较属性)

      let obj1 ='123';
      let obj2 ='abc';
      let obj3={
        id:10001,
        name:'ShangSan'
      };
      let obj4={
        id:10001,
        name:'ShangSan'
      };
      let obj5={
        id:10001,
        name:'ShangSan',
        address:'Beijing'
      };
      let fun1 = function(param) {
        console.log(arguments);
      };
      let fun3 = function(param) {
        console.log(arguments);
      };
      let mDate1 = new Date();
      let mDate2 = new Date();
      console.log(isDeepObjectEqual(obj1, obj1));//true
      console.log(isDeepObjectEqual(fun1, fun3));//true
      console.log(isDeepObjectEqual(mDate1, mDate2));//true
      console.log(isDeepObjectEqual(obj1, obj2));//false
      console.log(isDeepObjectEqual(obj3, obj4));//true
      console.log(isDeepObjectEqual(obj3, obj5));//false
      //比较个复杂的
      let mObjB={
          id:1001,
          name:'abc',
          isChinese:true,
          work:function(){
            console.log(arguments);
          }
      };
      let mObjA={
        id:1001,
          name:'abc',
          isChinese:true,
          work:function(){
            console.log(arguments);
          }
      };
      console.log(isDeepObjectEqual(mObjB, mObjA));//true

提醒

当然要是严谨,还可以比较两个对象的原型

  console.log(Object.getPrototypeOf(obj1)==Object.getPrototypeOf(obj2));//true

甚至可以把两个对象的原型的属性在进行比较。(这里就不展开了~~~)
利用上面的方法

const prototypesAreEqual = isDeepEqual(Object.getPrototypeOf(obj1),Object.getPrototypeOf(obj2))

相关文章

  • JavaScript 比较两个对象

    背景 对象的比较使用==和===比较,即使拥有相同的属性和相同的值,但很有可能不相等的。这是因为它们是通过它们的引...

  • 深度比较两个javaScript对象

  • Javascript比较的艺术

    我们该如何比较? 1.两个对象的比较 Javascript的比较中参杂了一些比较奇怪的特性,我们来看一些比较简单的...

  • javascript 深度比较两个对象是否相等

    代码 使用

  • JAVASCRIPT运算符

    javascript基本类型(指字符串和数值等内置类型)的比较是值的比较。javascript对象的比较是引用的比...

  • ES6 之 Promise

    Promise是JavaScript异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步...

  • json

    一、json是javascript对象表示法,类似于javascript对象的一种数据格式,目前这种数据格式比较流...

  • json

    一、json是javascript对象表示法,类似于javascript对象的一种数据格式,目前这种数据格式比较流...

  • JavaScript object对象大小比较研究

    JavaScript的基本类型进行大小比较时,能直接比较大小的,除了、 、 外,还有有如下几个: ...

  • 25.比较2个对象是否相等

    引用至:JavaScript专题之如何判断两个对象相等

网友评论

    本文标题:JavaScript 比较两个对象

    本文链接:https://www.haomeiwen.com/subject/yqhlhctx.html