如何使用Javascript或lodash对两个对象的属性进行浅层比较?

Sam*_*tar 15 javascript object-comparison

有没有办法我可以做一个浅层比较,不会下去比较Javascript或lodash中对象内部的对象内容?请注意,我确实检查了lodash,但似乎进行了深入的比较,我不想这样做.

var a = { x: 1, y: 2}
var b = { x: 1, y: 3}
Run Code Online (Sandbox Code Playgroud)

有没有办法比较ab

dhi*_*ilt 27

简单的ES6方法:

const shallowCompare = (obj1, obj2) =>
  Object.keys(obj1).length === Object.keys(obj2).length &&
  Object.keys(obj1).every(key => obj1[key] === obj2[key]);
Run Code Online (Sandbox Code Playgroud)

在这里,我添加了对象键数量相等性检查,以便下面的比较失败(一个通常不会进入帐户的重要案例):

shallowCompare({ x: 1, y: 3}, { x: 1, y: 3, a: 1}); // false
Run Code Online (Sandbox Code Playgroud)

2019年更新.根据Andrew Rasmussen的评论,我们还需要考虑undefined案例.以前的方法的问题是以下比较返回true:

({ foo: undefined })['foo'] === ({ bar: undefined })['foo'] // true
Run Code Online (Sandbox Code Playgroud)

因此,需要显式密钥存在检查.它可以通过以下方式完成hasOwnProperty:

const shallowCompare = (obj1, obj2) =>
  Object.keys(obj1).length === Object.keys(obj2).length &&
  Object.keys(obj1).every(key => 
    obj2.hasOwnProperty(key) && obj1[key] === obj2[key]
  );
Run Code Online (Sandbox Code Playgroud)

  • @AndrewRasmussen我更新了答案,并介绍了“未定义”情况。感谢您的评论和失败代码示例! (4认同)
  • 使用 `Object.prototype.hasOwnProperty.call(obj2, key)` 来传递 ESLint:https://eslint.org/docs/rules/no-prototype-builtins (4认同)
  • 这对于具有未定义值的键不起作用。`shallowCompare({foo:undefined,},{bar:undefined,}); //返回true` (2认同)

Pau*_*per 16

function areEqualShallow(a, b) {
    for(var key in a) {
        if(!(key in b) || a[key] !== b[key]) {
            return false;
        }
    }
    for(var key in b) {
        if(!(key in a) || a[key] !== b[key]) {
            return false;
        }
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 由于这很浅,areEqualShallow({a:{}}, {a:{}})是假的.

  • areEqualShallow({a:undefined}, {}) 是假的.

  • 这包括原型中的任何属性.

  • 这使用===比较.我认为这就是你想要的.NaN === NaN是一个可能产生意外结果的案例.如果===不是您想要的,请用您想要的比较代替.


编辑:如果每个对象中有相同的键,那么

function areEqualShallow(a, b) {
    for(var key in a) {
        if(a[key] !== b[key]) {
            return false;
        }
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

  • @sabithpocker,你的例子突出了"浅"和"深"比较之间的差异.然后浅层比较不平等; 深刻的比较使他们平等. (2认同)

mpe*_*pen 5

这是从fbjs解除的:

/**
 * Copyright (c) 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @typechecks
 *
 */

/*eslint-disable no-self-compare */

'use strict';

var hasOwnProperty = Object.prototype.hasOwnProperty;

/**
 * inlined Object.is polyfill to avoid requiring consumers ship their own
 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
 */
function is(x, y) {
    // SameValue algorithm
    if (x === y) {
        // Steps 1-5, 7-10
        // Steps 6.b-6.e: +0 != -0
        return x !== 0 || 1 / x === 1 / y;
    } else {
        // Step 6.a: NaN == NaN
        return x !== x && y !== y;
    }
}

/**
 * Performs equality by iterating through keys on an object and returning false
 * when any key has values which are not strictly equal between the arguments.
 * Returns true when the values of all keys are strictly equal.
 */
function shallowEqual(objA, objB) {
    if (is(objA, objB)) {
        return true;
    }

    if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
        return false;
    }

    var keysA = Object.keys(objA);
    var keysB = Object.keys(objB);

    if (keysA.length !== keysB.length) {
        return false;
    }

    // Test for A's keys different from B.
    for (var i = 0; i < keysA.length; i++) {
        if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
            return false;
        }
    }

    return true;
}

module.exports = shallowEqual;
Run Code Online (Sandbox Code Playgroud)

如果您需要使用它,我建议将它复制到您自己的项目中,因为他们的自述文件明确指出他们可以在没有警告的情况下删除或修改此代码以及库中的任何其他代码。


Rie*_*end 5

Paul Draper 的解决方案可以通过删除第二遍中的比较来优化。

function areEqualShallow(a, b) {
  for (let key in a) {
    if (!(key in b) || a[key] !== b[key]) {
      return false;
    }
  }
  for (let key in b) {
    if (!(key in a)) {
      return false;
    }
  }
  return true;
}
Run Code Online (Sandbox Code Playgroud)


Ada*_* Hv 5

请记住,它只适用于浅层,仅适用于字符串和数字

function equals(obj1, obj2) {
  return Object.keys(obj1)
    .concat(Object.keys(obj2))
    .every(key => {
      return obj1[key] === obj2[key];
    });
}
Run Code Online (Sandbox Code Playgroud)