• 简体中文
  • shallow

    shallow 让你能对简单的数据结构进行快速检查。当你处理的数据结构内部没有嵌套对象或数组时,它能有效识别顶层属性的变化。

    NOTE

    shallow 可以做快速比较,但请记住它的局限性。

    const equal = shallow(a, b)

    类型

    签名

    shallow<T>(a: T, b: T): boolean

    参考

    shallow(a, b)

    参数

    • a:第一个值。
    • b:第二个值。

    返回值

    当 a 和 b 基于其顶层属性的浅比较判定为相等时,shallow 返回 true;否则应返回 false。

    用法

    比较原始值

    在比较 string、number、boolean 和 BigInt 这类原始值时,如果值相同,Object.is 和 shallow 函数都会返回 true。这是因为原始值按实际值比较,而不是按引用比较。

    const stringLeft = 'John Doe'
    const stringRight = 'John Doe'
    
    Object.is(stringLeft, stringRight) // -> true
    shallow(stringLeft, stringRight) // -> true
    
    const numberLeft = 10
    const numberRight = 10
    
    Object.is(numberLeft, numberRight) // -> true
    shallow(numberLeft, numberRight) // -> true
    
    const booleanLeft = true
    const booleanRight = true
    
    Object.is(booleanLeft, booleanRight) // -> true
    shallow(booleanLeft, booleanRight) // -> true
    
    const bigIntLeft = 1n
    const bigIntRight = 1n
    
    Object.is(bigIntLeft, bigIntRight) // -> true
    shallow(bigIntLeft, bigIntRight) // -> true

    比较对象

    比较对象时,理解 Object.is 和 shallow 函数的工作方式很重要,因为它们处理比较的方式不同。

    shallow 函数返回 true,因为 shallow 执行的是对象的浅比较。它会检查顶层属性及其值是否相同。在这个例子中,objectLeft 和 objectRight 的顶层属性(firstName、lastName 和 age)及其值完全相同,所以 shallow 认为它们相等。

    const objectLeft = {
      firstName: 'John',
      lastName: 'Doe',
      age: 30,
    }
    const objectRight = {
      firstName: 'John',
      lastName: 'Doe',
      age: 30,
    }
    
    Object.is(objectLeft, objectRight) // -> false
    shallow(objectLeft, objectRight) // -> true

    比较 Set

    比较 Set 时,理解 Object.is 和 shallow 函数的工作方式很重要,因为它们处理比较的方式不同。

    shallow 函数返回 true,因为 shallow 执行的是 Set 的浅比较。它会检查顶层属性(在这里就是 Set 本身)是否相同。由于 setLeft 和 setRight 都是 Set 对象的实例,并且包含相同的元素,所以 shallow 认为它们相等。

    const setLeft = new Set([1, 2, 3])
    const setRight = new Set([1, 2, 3])
    
    Object.is(setLeft, setRight) // -> false
    shallow(setLeft, setRight) // -> true

    比较 Map

    比较 Map 时,理解 Object.is 和 shallow 函数的工作方式很重要,因为它们处理比较的方式不同。

    shallow 返回 true,因为 shallow 执行的是 Map 的浅比较。它会检查顶层属性(在这里就是 Map 本身)是否相同。由于 mapLeft 和 mapRight 都是 Map 对象的实例,并且包含相同的键值对,所以 shallow 认为它们相等。

    const mapLeft = new Map([
      [1, 'one'],
      [2, 'two'],
      [3, 'three'],
    ])
    const mapRight = new Map([
      [1, 'one'],
      [2, 'two'],
      [3, 'three'],
    ])
    
    Object.is(mapLeft, mapRight) // -> false
    shallow(mapLeft, mapRight) // -> true

    疑难解答

    对象相同但比较返回 false

    shallow 函数执行的是浅比较。浅比较只检查两个对象的顶层属性是否相等,它不会检查嵌套对象或深层嵌套的属性。换句话说,它只比较属性的引用。

    在下面的示例中,shallow 函数返回 false,因为它只比较顶层属性及其引用。两个对象中的 address 属性都是嵌套对象,尽管它们的内容完全相同,但引用不同。因此 shallow 认为它们不同,结果就是 false。

    const objectLeft = {
      firstName: 'John',
      lastName: 'Doe',
      age: 30,
      address: {
        street: 'Kulas Light',
        suite: 'Apt. 556',
        city: 'Gwenborough',
        zipcode: '92998-3874',
        geo: {
          lat: '-37.3159',
          lng: '81.1496',
        },
      },
    }
    const objectRight = {
      firstName: 'John',
      lastName: 'Doe',
      age: 30,
      address: {
        street: 'Kulas Light',
        suite: 'Apt. 556',
        city: 'Gwenborough',
        zipcode: '92998-3874',
        geo: {
          lat: '-37.3159',
          lng: '81.1496',
        },
      },
    }
    
    Object.is(objectLeft, objectRight) // -> false
    shallow(objectLeft, objectRight) // -> false

    如果去掉 address 属性,浅比较就会按预期工作,因为所有顶层属性都会是原始值或指向相同值的引用:

    const objectLeft = {
      firstName: 'John',
      lastName: 'Doe',
      age: 30,
    }
    const objectRight = {
      firstName: 'John',
      lastName: 'Doe',
      age: 30,
    }
    
    Object.is(objectLeft, objectRight) // -> false
    shallow(objectLeft, objectRight) // -> true

    在这个修改后的示例中,objectLeft 和 objectRight 具有相同的顶层属性和原始值。由于 shallow 函数只比较顶层属性,它会返回 true,因为两个对象中的原始值(firstName、lastName 和 age)完全相同。

    比较原型不同的对象

    shallow 函数会检查两个对象是否具有相同的原型。如果它们的原型在引用上不同,shallow 将返回 false。这个比较通过以下代码完成:

    Object.getPrototypeOf(a) === Object.getPrototypeOf(b)
    WARNING

    使用对象字面量({})或 new Object() 创建的对象默认继承自 Object.prototype。而使用 Object.create(proto) 创建的对象继承自你传入的 proto——它可能并不是 Object.prototype。

    const a = Object.create({}) // -> prototype is `{}`
    const b = {} // -> prototype is `Object.prototype`
    
    shallow(a, b) // -> false