Underscore contains (_.contains) 在对象类型上的应用

阅读时长 4 分钟读完

Underscore.js 是一个流行的 JavaScript 库,提供了许多实用的函数来操作数组、集合、对象等数据类型。其中,contains 函数可以用于判断一个值是否存在于一个数组或字符串中。但是,在对象类型上使用 contains 函数有一些需要注意的地方。

对象类型的 contains 函数

在 Underscore.js 中,contains 函数支持以下两种调用方式:

  • _.contains(array, value):判断 value 是否存在于 array 数组中;
  • _.contains(object, value):判断 value 是否为 object 对象的一个属性值。

下面我们重点介绍第二种调用方式的使用方法。

例如,我们有一个对象数组,每个对象都有一个 name 属性:

我们可以使用 contains 函数来判断某个名字是否存在于该数组中:

这里返回了 false,因为 contains 函数使用的是 JavaScript 的“引用比较”,即只有当两个对象引用同一个内存地址时才会返回 true。而在上面的代码中,{ name: 'Bob' } 是一个新的对象,和数组中的 { name: 'Bob', age: 30 } 不是同一个对象,因此返回了 false。

那么该如何正确地使用 contains 函数呢?我们需要使用 Underscore.js 提供的 find 函数来查找数组中满足条件的对象。例如,要判断名字为 Bob 的用户是否存在,可以这样写:

这里先使用了 find 函数查找到第一个名字为 Bob 的用户对象,如果返回的结果不是 undefined,则说明该对象存在于数组中。

深度比较

上述例子中的问题是由于 JavaScript 对象的引用比较导致的。但是,如果我们想要在对象类型上进行“值比较”呢?例如,以下对象数组中两个对象的属性值相同:

-- -------------------- ---- -------
--- ----- - -
  - --- -- ------ -------- ------ --- --
  - --- -- ------ --------- ------ --- --
  - --- -- ------ ------- ------ --- --
  - --- -- ------ ------- ------ --- --
  - --- -- ------ --------- ------ --- --
  - --- -- ------ ------------ ------ --- -
--
--- ------- - - --- -- ------ -------- ------ --- --

此时,我们希望通过 contains 函数来判断 newItem 是否在 items 中。但是,由于 newItem 和 items 中的对象并不是同一个对象,因此简单的调用 contains 函数会得到错误的结果:

为了实现“值比较”,我们需要使用 Underscore.js 提供的 isEqual 函数来比较对象。可以自定义一个新的包装函数:

这里的 containsValue 函数使用 some 函数遍历集合中的每个元素,并使用 isEqual 函数比较集合中的元素和目标元素是否相等。如果找到了相等的元素,则返回 true;否则返回 false。

通过调用新的 containsValue 函数,我们可以得到正确的结果:

结论

在对象类型上使用 contains 函数需要注意以下几点:

  • 对象类型的 contains 函数是通过“引用比较”来判断对象

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/27667

纠错
反馈