观察 ES6 Maps 和 Sets 的变化
Observing changes to ES6 Maps and Sets
有什么方法可以观察 ES6 Maps 和 Sets 的添加和删除吗? Object.observe 不起作用,因为它仅适用于观察对象的直接属性。假设可以观察到 size
属性,但不会提供确切更改内容的指示。另一个想法是用代理版本替换对象的 set
和 get
函数。有没有更好的办法?如果不是,我很惊讶在为 ES6 编写提案时没有人想到这一点。
不,没有办法用香草做到这一点 Map/Set。一般来说,单独观察对象属性是有争议的(这就是为什么 Object.observe
只是一个提议,而不是规范的接受部分)。观察私有状态,例如 Map 或 Set(或 Date 或 Promise,就此而言)的内部结构,绝对不在 table.
上
另请注意,由于 size
是 getter,而不是数据 属性,因此 Object.observe
不会通知您对其进行更改。
正如您提到的,您可以通过变异者和观察者之间的协作来实现这样的 "observation"。您可以使用普通 Map/Set 加上侧通道(例如返回 { Map, EventEmitter }
对象的函数)或通过为此目的定制的子类或为此目的创建的特定实例来执行此操作。
Set/Map
的子类目前不起作用。这个方法怎么样(只是仓促的例子)?
//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}
有什么方法可以观察 ES6 Maps 和 Sets 的添加和删除吗? Object.observe 不起作用,因为它仅适用于观察对象的直接属性。假设可以观察到 size
属性,但不会提供确切更改内容的指示。另一个想法是用代理版本替换对象的 set
和 get
函数。有没有更好的办法?如果不是,我很惊讶在为 ES6 编写提案时没有人想到这一点。
不,没有办法用香草做到这一点 Map/Set。一般来说,单独观察对象属性是有争议的(这就是为什么 Object.observe
只是一个提议,而不是规范的接受部分)。观察私有状态,例如 Map 或 Set(或 Date 或 Promise,就此而言)的内部结构,绝对不在 table.
另请注意,由于 size
是 getter,而不是数据 属性,因此 Object.observe
不会通知您对其进行更改。
正如您提到的,您可以通过变异者和观察者之间的协作来实现这样的 "observation"。您可以使用普通 Map/Set 加上侧通道(例如返回 { Map, EventEmitter }
对象的函数)或通过为此目的定制的子类或为此目的创建的特定实例来执行此操作。
Set/Map
的子类目前不起作用。这个方法怎么样(只是仓促的例子)?
//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}