rxjs:扫描累加器

rxjs:扫描累加器,rxjs,rxjs6,Rxjs,Rxjs6,我(错误地)认为扫描操作员每次都会返回一个新对象。我最近发现情况并非如此 我已经从中分出一个例子来说明我的意思 看看代码: const subject = new Rx.Subject(); const example = subject.scan((acc, curr) => { console.log('Accumulator', acc); return Object.assign({}, acc, curr) }, {}); //log accumulated

我(错误地)认为扫描操作员每次都会返回一个新对象。我最近发现情况并非如此

我已经从中分出一个例子来说明我的意思

看看代码:

const subject = new Rx.Subject();

const example = subject.scan((acc, curr) => {
    console.log('Accumulator', acc);
    return Object.assign({}, acc, curr)
}, {});

//log accumulated values
const subscribe = example.subscribe(val => {
    val.mutating = 'test'
    console.log('Accumulated object:', val)
});

//next values into subject, adding properties to object
subject.next({name: 'Joe'}); 
// {name: 'Joe'}

subject.next({age: 30}); 
// {name: 'Joe', age: 30}

subject.next({favoriteLanguage: 'JavaScript'}); 
// {name: 'Joe', age: 30, favoriteLanguage: 'JavaScript'}
我正在对
subscription
流中传递的
val
进行变异,并在
scan
累加器函数中注销
累加器的值

查看控制台,它显示累加器包含
变异:“test”
,在第一次和后续通过后:

除非我弄错了,否则这表明我可以在订阅之前和订阅中的任何位置变异流对象。我想这并不奇怪,因为它是一个对象引用。但是,我认为
scan
操作符总是会返回一个新对象,以防止其内部累加器发生变异

我的第一个想法是映射一个新对象,如下所示:

scan((acc, curr) => Object.assign({}, acc, curr), {}),
map(data=>Object.assign({}, data))
但我觉得这很奇怪

我所展示的行为是预期的还是我不理解这一切是如何运作的?如何防止累加器发生变异


谢谢

是的,您正在更改的是对象引用->
acc
。您可以像下面这样冻结对象以防止其发生突变

 return Object.freeze(Object.assign({},acc, curr));

你在仔细地复制来自
curr
的所有内容,那么为什么变异持续存在令人惊讶呢?是的,您正在构建一个新对象,但具有所有旧属性。我认为扫描操作符会在每次缩小时返回一个新对象