09月19, 2021

Object Equality in JavaScript (数组,对象相等性比较)

Object Equality in JavaScript (数组,对象相等性比较)


var jangoFett = {
    occupation: "Bounty Hunter",
    genetics: "superb"
};

var bobaFett = {
    occupation: "Bounty Hunter",
    genetics: "superb"
};

// Outputs: false
console.log(bobaFett === jangoFett);

我们都知道,jangoFett == bobaFett 返回的值是false,下面请写一个方法,如果键值对都是一样的(只需要原生相等),则认为两个对象是相等的.

方法1:(针对数组,对象,非嵌套的情况)单层数据结构


function isEquivalent(a, b) {
    // Create arrays of property names
    var aProps = Object.getOwnPropertyNames(a);
    var bProps = Object.getOwnPropertyNames(b);

    // If number of properties is different,
    // objects are not equivalent
    if (aProps.length != bProps.length) {
        return false;
    }

    for (var i = 0; i < aProps.length; i++) {
        var propName = aProps[i];

        // If values of same property are not equal,
        // objects are not equivalent
        if (a[propName] !== b[propName]) {
            return false;
        }
    }

    // If we made it this far, objects
    // are considered equivalent
    return true;
}

// Outputs: true
console.log(isEquivalent(bobaFett, jangoFett));


如果针对嵌套的情况,则该方法不适用,例如如下测试:

console.log(isEquivalent({ a: { c: [1] }, b: 2 }, { b: 2, a: { c: [1] } }));

// output:false

控制台测试对比图

针对数组,对象嵌套情况:


function isDeepEqual(obj1, obj2, testPrototypes = false) {

    if (obj1 === obj2) {
      return true;
    }

    if (typeof obj1 === "function" && typeof obj2 === "function") {
      return obj1.toString() === obj2.toString();
    }

    if (obj1 instanceof Date && obj2 instanceof Date) {
      return obj1.getTime() === obj2.getTime();
    }

    if (Object.prototype.toString.call(obj1) !== Object.prototype.toString.call(obj2) || typeof obj1 !== "object") {
      return false;
    }

const prototypesAreEqual = testPrototypes ? isDeepEqual(Object.getPrototypeOf(obj1), Object.getPrototypeOf(obj2), true) : true;

    const obj1Props = Object.getOwnPropertyNames(obj1);
    const obj2Props = Object.getOwnPropertyNames(obj2);
    console.log('result obj1Props obj2Props', obj1Props, obj2Props)
    console.log('result', obj1Props.length === obj2Props.length);
    console.log('result prototypesAreEqual', prototypesAreEqual);
    console.log('result obj1Props.every(prop=>isDeepEqual(obj1[prop],obj2[prop])', obj1Props.every(prop => isDeepEqual(obj1[prop], obj2[prop])));


    return (obj1Props.length === obj2Props.length && prototypesAreEqual && obj1Props.every(prop => isDeepEqual(obj1[prop], obj2[prop])))
  }

  console.log('result', isDeepEqual({ a: { c: [1] }, b: 2 }, { b: 2, a: { c: [1] } },false)); //true

  console.log('result array',isDeepEqual([1,2,[3]],[1,2,[3]])); // true

控制台打印

方法3:使用loadsh的isEqual方法

如果项目中有使用loadsh库的话,里面的isEqual方法也是深层次的比较的.如下:

执行深比较来确定两者的值是否相等。

注意:

这个方法支持比较 arrays, array buffers, booleans, date objects, error objects, maps, numbers, Object objects, regexes, sets, strings, symbols, 以及 typed arrays. Object 对象值比较自身的属性,不包括继承的和可枚举的属性。 不支持函数和DOM节点比较。


    var obj1 = { a: { c: [1] }, b: 2 };
    var obj2 = { b: 2, a: { c: [1] } };
    console.log('result',this.$lodash.isEqual(obj1,obj2)); // true

    var obj1 = [1,2,3,[4,[5]]];
    var obj2 = [1,2,3,[4,[5]]];;
    console.log('result',this.$lodash.isEqual(obj1,obj2)); // true

本文链接:https://901web.com/post/object-equality-in-javascript.html

-- EOF --

Comments

请在后台配置评论类型和相关的值。