Dictionary 观察ES6地图和集合的变化

Dictionary 观察ES6地图和集合的变化,dictionary,set,ecmascript-6,Dictionary,Set,Ecmascript 6,是否有任何方法可以观察ES6地图和集合的添加和删除?不起作用,因为它仅适用于观察对象的直接属性。假设可以观察到大小属性,但不会提供确切的变化指示。另一个想法是用代理版本替换对象的set和get函数。有更好的办法吗?如果没有,我很惊讶在为ES6编写提案时没有人想到这一点。不,用普通地图/集合无法做到这一点。一般来说,仅观察对象属性是有争议的(这就是为什么object.observe只是一个建议,而不是规范中可接受的部分)。观察私有状态,比如地图或场景的内部(或者日期或承诺,就这一点而言),绝对不是

是否有任何方法可以观察ES6地图和集合的添加和删除?不起作用,因为它仅适用于观察对象的直接属性。假设可以观察到
大小
属性,但不会提供确切的变化指示。另一个想法是用代理版本替换对象的
set
get
函数。有更好的办法吗?如果没有,我很惊讶在为ES6编写提案时没有人想到这一点。

不,用普通地图/集合无法做到这一点。一般来说,仅观察对象属性是有争议的(这就是为什么
object.observe
只是一个建议,而不是规范中可接受的部分)。观察私有状态,比如地图或场景的内部(或者日期或承诺,就这一点而言),绝对不是摆在桌面上

还要注意,由于
size
是一个getter,而不是一个数据属性,
Object.observe
不会通知您对它的更改


正如您所提到的,您可以通过突变子和观察者之间的协作来实现这种“观察”。您可以使用普通映射/集和侧通道(例如,返回
{Map,EventEmitter}
对象的函数)执行此操作,也可以通过为此目的定制的子类或为此目的创建的特定实例执行此操作。

集/Map
进行子类化目前不起作用。这个方法怎么样(只是草率的例子)


代理几乎是你唯一的选择。对它们进行子类化并覆盖
set
/
get
,是的。@user5321531:“Object.observe不起作用,因为它只适用于被观察对象的直接属性”@FelixKling好的,谢谢你的输入。这就是为什么代理应该支持映射和设置,而不仅仅是对象和函数
//ECMAScript 2015
class XMap
{
  constructor(iterable, observer = null)
  {
    this._map      = new Map(iterable);
    this._observer = observer;
    this._changes  = {};
  }
  set(key, value)
  {
    this._changes.prev = this._map.get(key);
    this._changes.new  = value;
    this._map.set(key, value);

    if(this._observer !== null)
    {
      this._observer(this._changes);
    }
  }
  get(key)
  {
    return this._map.get(key); 
  }
}

var m = new XMap([[0, 1]], changes => console.log(changes));

m.set(0,5);  // console: Object {prev: 1, new: 5}
m.set(0,15); // console: Object {prev: 5, new: 15}