比较JavaScript中的类型,值和对象(不重复)

时间:2017-07-23 18:18:06

标签: javascript recursion types javascript-objects

修改:这不是一个重复的问题。 我的功能不同,并没有使用直接对象比较方法。

我正在阅读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};`

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

我已经完成了纸上的整个代码,一行一行,不知道我要做什么,或者递归调用是不是正确地比较了属性,或者我只是不做知识了。

有人能提供解决方案吗?或者,如果可能的话,更好的方法或思考过程来解决这个案子?

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

1 个答案:

答案 0 :(得分:0)

有许多技术可以进行深度对象比较,但最可靠的技术也可能是最简单的...在每个要比较的对象上使用 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()出于安全原因,默认情况下会删除存储函数的属性,但是使用可选的“replacer”参数,您实际上可以手动将其保存到字符串中。