JS Set.has()方法会进行浅层检查吗? [英] Does JS Set.has() method do shallow checks?

查看:35
本文介绍了JS Set.has()方法会进行浅层检查吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一组对象,例如

If I have a set of objects, like

const s = new Set();
s.add({a: 1, b: 2});
s.add({a: 2, b: 2});

我会做

s.has({a: 1, b: 2});

我将获得积极的结果吗? Set 如何处理引用类型?有没有办法告诉它使用自定义检查器/谓词?

Will I have a positive result? How does Set handle reference types? Is there a way to tell it to use custom checker/predicate?

推荐答案

期望任何本机JavaScript API均通过引用而不是内容(包括浅表比较)来比较对象:

It's expected that any native JavaScript API compare objects by their references and not their contents (including shallow comparison):

({a: 1, b: 2}) !== ({a: 1, b: 2})

Set 不是排除项,它

Set isn't an exclusion, it does === comparison for every value but NaN when it looks up values with has or stores unique values.

这可以通过扩展 Set 并在 has 等方法中使用深度比较来实现,但效率不高.

This could be achieved by extending Set and using deep comparison in has, etc. methods but it would be inefficient.

一种更有效的方法是使用 Map ,因为条目应通过规范化的键进行存储和检索,但是应该存储实际的对象.这可以通过使用 JSON.stringify 来完成,但是对象键也应该优先排序,因此第三方实现如

A more efficient way is to use Map instead, because entries should be stored and retrieved by normalized keys, but actual objects are supposed to be stored. This can be done by using JSON.stringify, but object keys should be preferable sorted as well, so third-party implementation like json-stable-stringify may be used.

在这一点上,扩展 Set Map 可能没有太多好处,因为大多数方法都应被覆盖:

At this point there are may be not much benefits from extending either Set or Map because most methods should be overridden:

class DeepSet {
  constructor (iterable = []) {
    this._map = new Map();
    for (const v of iterable) {
      this.add(v);
    }
  }

  _getNormalizedKey(v) {
    // TODO: sort keys
    return (v && typeof v === 'object') ? JSON.stringify(v) : v;
  }

  add(v) {
    this._map.set(this._getNormalizedKey(v), v);
    return this;
  }

  has(v) {
    return this._map.has(this._getNormalizedKey(v));
  }

  // etc
}

请注意,此集合仅适用于可以正确序列化为JSON的普通对象.可能还有其他方法可以序列化对象内容,但是没有一种方法可以正确处理所有可能的值,例如符号和类实例.

Notice that this set is intended only for plain objects that can be correctly serialized to JSON. There may be other ways to serialize object contents but none of them will handle all possible values correctly, e.g. symbols and class instances.

这篇关于JS Set.has()方法会进行浅层检查吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆