我(错误地)觉得扫描操作员每次通过总是返回一个新对象。我最近发现情况并非如此。
我已经将learnrxjs.io的示例进行了分叉,以说明我的意思here。
看一下代码:
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'}
我正在对val
中沿流传递的subscription
进行突变,并在accumulator
累加器函数中注销scan
的值。
在控制台上,它显示累加器在第一遍和后续遍历之后包含mutating:"test"
:
除非我弄错了,否则这表明我可以在订阅之前和之后的任何地方对流对象进行突变。我想这并不奇怪,因为它是一个对象引用。但是,我认为scan
运算符将始终返回一个新对象,以防止其内部累加器发生突变...
我首先想到的是这样映射一个新对象:
scan((acc, curr) => Object.assign({}, acc, curr), {}),
map(data=>Object.assign({}, data))
但这对我来说似乎很奇怪。
我所表现出的行为是预期的还是我不了解这一切的工作方式?如何防止累加器发生突变?
谢谢
答案 0 :(得分:3)
是的,您要更改的是对象引用-> acc
。您可以如下冻结对象,以阻止其变异。
return Object.freeze(Object.assign({},acc, curr));