【问题标题】:Comparing Types, Values and Objects in JavaScript (Not a duplicate) [duplicate]比较 JavaScript 中的类型、值和对象(不重复)[重复]
【发布时间】:2017-12-29 07:44:17
【问题描述】:

编辑:这不是重复的问题。 我的功能不同,不使用直接的对象比较方法。

我正在阅读 Eloquent Javascript 书籍,在第四章中,最后一个练习需要一个函数 deepEqual,它接受两个参数并比较它们。

  • 如果参数是不同的类型,它应该返回 false。
  • 如果参数是相同类型和相同的值,它应该返回true 否则,返回 false。
  • 如果参数都是对象,则应比较它们的属性和值。如果两个对象以相同的顺序具有相同的属性和值,则函数调用应返回 true。例如,如果我们有以下对象:object1 = {a: 1, b: 2}, object2 = {a: 1, b: 2}, object3 = {a: 2, b: 1},比较 object1 和 object2 应该返回 true,但比较 object1 和 object3 应该返回 false。
  • 最后,如果对象有嵌套对象作为参数,则递归调用 deepEqual 来比较嵌套对象。

所以,这是我的解决方案。它与 if/else 语句相当复杂,请原谅。

function deepEqual(obj1, obj2){

  var checkForSameTypes = (typeof obj1 === typeof obj2);

  if(checkForSameTypes === true){

    //same type but not objects
    if(typeof obj1 !== "object" && typeof obj2 !== "object") {
      if(obj1 == obj2){
        return true;
      }else{
        return false;
      }

     // same type and objects
    }else if(typeof obj1 === "object" && typeof obj2 === "object"){

      //loop first object and compare properties with 2nd object
      for(var prop in obj1){
        if(obj2.hasOwnProperty(prop)) {

        //if 2nd object has property "prop" compare
          if(typeof obj1[prop] === "object" && typeof obj2[prop] === "object"){
            //recursive call
            deepEqual(obj1[prop], obj2[prop]);
          }else if(obj1[prop] === obj2[prop]) {
            //loop goes on to the next property
            continue; 
          }else if(obj1[prop] !== obj2[prop]){
            return false;
          } 
        //it doesn't have property "prop" so return false
        } else {
          return false;
        }
      }
      //finishes loop and all properties are the same
      return true; 
    }
   // they are not the same types so return false
  } else {
    return false;
  }
}

问题

该函数可以正常工作,除非参数是具有嵌套对象的对象。 以这些对象为例

var type = {go: {inside: "yes"}, come: 2}

var see = {go: {inside: "no"}, come: 2} 

var fine = {when: 3, go: 4};`

当我将typesee 与对deepEqual(type,see); 的调用进行比较时,这将返回true,这是错误的,因为嵌套对象go 的属性值不同。

我已经在纸上逐行浏览了整个代码,但不知道我必须做什么,或者递归调用是否无法正确比较属性,或者我只是还不知道.

谁能提供解决方案?或者如果可能的话,有更好的方法或思维过程来解决这个问题?

注意:代码只比较对象的属性和值。它不需要比较构造函数或原型。

【问题讨论】:

  • 类似,但不是重复的。我的问题完全不同

标签: javascript recursion types javascript-objects


【解决方案1】:

进行深度对象比较的技术有很多,但可能最可靠的一种也是最简单的...在每个要比较的对象上使用JSON.stringify(obj),将它们转换为字符串并然后比较字符串。

var a = {go: {inside: "yes"}, come: 2, flag: true}
var b = {go: {inside: "yes"}, come: 2, flag: true} 
var c = {go: {inside: "yes"}, come: 1}
var d = {go: {inside: "yes"}, come: 2, flag: "true"} 

function deepEqual(obj1, obj2){
  // Convert both objects to strings and compare them:
  console.log(JSON.stringify(obj1) === JSON.stringify(obj2)); 
}

deepEqual(a,b); // true
deepEqual(b,c); // false
deepEqual(a,d); // false

现在,请记住,出于安全原因,JSON.stringify() 默认情况下会去除存储函数的属性,但使用可选的“替换器”参数,您实际上可以手动将其保存到字符串中。

【讨论】:

  • 这个问题是,它会认为{a: 1, b: 1}{b: 1, a: 1} 不同,并忽略任何不能用JSON 表示的嵌套对象,例如SetMap、..等
  • @trincot 得分。
  • 您好 Scott,感谢您的回答,不幸的是,我不允许使用抽象,例如 JSON.stringify()
猜你喜欢
  • 2021-09-15
  • 2016-07-26
相关资源
最近更新 更多